morpheus-cli 5.3.2 → 5.3.3

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/lib/morpheus/api/accounts_interface.rb +4 -30
  4. data/lib/morpheus/api/api_client.rb +12 -0
  5. data/lib/morpheus/api/instances_interface.rb +18 -5
  6. data/lib/morpheus/api/load_balancer_pools_interface.rb +9 -0
  7. data/lib/morpheus/api/load_balancer_types_interface.rb +9 -0
  8. data/lib/morpheus/api/load_balancer_virtual_servers_interface.rb +9 -0
  9. data/lib/morpheus/api/load_balancers_interface.rb +4 -53
  10. data/lib/morpheus/api/network_routers_interface.rb +56 -0
  11. data/lib/morpheus/api/secondary_read_interface.rb +25 -0
  12. data/lib/morpheus/api/secondary_rest_interface.rb +42 -0
  13. data/lib/morpheus/api/virtual_images_interface.rb +23 -2
  14. data/lib/morpheus/cli/apps.rb +3 -2
  15. data/lib/morpheus/cli/cli_command.rb +21 -14
  16. data/lib/morpheus/cli/cli_registry.rb +55 -2
  17. data/lib/morpheus/cli/cloud_resource_pools_command.rb +169 -133
  18. data/lib/morpheus/cli/clusters.rb +51 -33
  19. data/lib/morpheus/cli/instances.rb +292 -174
  20. data/lib/morpheus/cli/invoices_command.rb +79 -99
  21. data/lib/morpheus/cli/library_cluster_layouts_command.rb +20 -0
  22. data/lib/morpheus/cli/load_balancer_types.rb +37 -0
  23. data/lib/morpheus/cli/load_balancers.rb +149 -314
  24. data/lib/morpheus/cli/log_settings_command.rb +7 -3
  25. data/lib/morpheus/cli/mixins/load_balancers_helper.rb +156 -0
  26. data/lib/morpheus/cli/mixins/print_helper.rb +11 -0
  27. data/lib/morpheus/cli/mixins/provisioning_helper.rb +123 -101
  28. data/lib/morpheus/cli/mixins/rest_command.rb +657 -0
  29. data/lib/morpheus/cli/monitoring_checks_command.rb +2 -0
  30. data/lib/morpheus/cli/network_routers_command.rb +1183 -185
  31. data/lib/morpheus/cli/networks_command.rb +194 -101
  32. data/lib/morpheus/cli/option_parser.rb +25 -17
  33. data/lib/morpheus/cli/option_types.rb +42 -45
  34. data/lib/morpheus/cli/tenants_command.rb +18 -20
  35. data/lib/morpheus/cli/vdi_pools_command.rb +4 -1
  36. data/lib/morpheus/cli/version.rb +1 -1
  37. data/lib/morpheus/cli/virtual_images.rb +249 -29
  38. data/lib/morpheus/cli.rb +1 -0
  39. data/lib/morpheus/ext/string.rb +41 -0
  40. data/lib/morpheus/formatters.rb +4 -0
  41. data/morpheus-cli.gemspec +1 -1
  42. metadata +13 -4
@@ -564,13 +564,10 @@ class Morpheus::Cli::Clusters
564
564
 
565
565
  cluster_payload['layout'] = {id: layout['id']}
566
566
 
567
- # Plan
567
+ # Provision Type
568
568
  provision_type = (layout && layout['provisionType'] ? layout['provisionType'] : nil) || get_provision_type_for_zone_type(cloud['zoneType']['id'])
569
- service_plan = prompt_service_plan(cloud['id'], provision_type, options)
570
569
 
571
- if service_plan
572
- server_payload['plan'] = {'id' => service_plan['id'], 'code' => service_plan['code'], 'options' => prompt_service_plan_options(service_plan, options)}
573
- end
570
+ api_params = {zoneId: cloud['id'], siteId: group['id'], layoutId: layout['id'], groupTypeId: cluster_type['id'], provisionTypeId: provision_type['id']}
574
571
 
575
572
  # Controller type
576
573
  server_types = @server_types_interface.list({max:1, computeTypeId: cluster_type['controllerTypes'].first['id'], zoneTypeId: cloud['zoneType']['id'], useZoneProvisionTypes: true})['serverTypes']
@@ -581,22 +578,47 @@ class Morpheus::Cli::Clusters
581
578
  controller_type = server_types.first
582
579
  controller_provision_type = controller_type['provisionType'] ? (@provision_types_interface.get(controller_type['provisionType']['id'])['provisionType'] rescue nil) : nil
583
580
 
584
- if controller_provision_type && resource_pool = prompt_resource_pool(group, cloud, service_plan, controller_provision_type, options)
585
- server_payload['config']['resourcePool'] = resource_pool['externalId']
581
+ if controller_provision_type && resource_pool = prompt_resource_pool(group, cloud, nil, controller_provision_type, options)
582
+ server_payload['config']['resourcePoolId'] = resource_pool['id']
583
+ api_params['config'] ||= {}
584
+ api_params['config']['resourcePool'] = resource_pool['id']
585
+ api_params['resourcePoolId'] = resource_pool['id']
586
+ api_params['zonePoolId'] = resource_pool['id']
586
587
  end
587
588
  end
588
589
 
590
+ # Service Plan
591
+ service_plan = prompt_service_plan(api_params, options)
592
+
593
+ if service_plan
594
+ server_payload['plan'] = {'id' => service_plan['id'], 'code' => service_plan['code'], 'options' => prompt_service_plan_options(service_plan, options)}
595
+ api_params['planId'] = service_plan['id']
596
+ end
597
+
589
598
  # Multi-disk / prompt for volumes
590
- volumes = options[:volumes] || prompt_volumes(service_plan, options.merge({'defaultAddFirstDataVolume': true}), @api_client, {zoneId: cloud['id'], siteId: group['id']})
599
+ volumes = options[:volumes] || prompt_volumes(service_plan, options.merge({'defaultAddFirstDataVolume': true}), @api_client, api_params)
591
600
 
592
601
  if !volumes.empty?
593
602
  server_payload['volumes'] = volumes
594
603
  end
595
604
 
605
+ # Options / Custom Config
606
+ option_type_list =
607
+ ((controller_type['optionTypes'].reject { |type| !type['enabled'] || type['fieldComponent'] } rescue []) + layout['optionTypes'] +
608
+ (cluster_type['optionTypes'].reject { |type| !type['enabled'] || !type['creatable'] || type['fieldComponent'] } rescue [])).sort { |type| type['displayOrder'] }
609
+
610
+ # KLUDGE: google zone required for network selection
611
+ if option_type = option_type_list.find {|type| type['code'] == 'computeServerType.googleLinux.googleZoneId'}
612
+ server_payload.deep_merge!(Morpheus::Cli::OptionTypes.prompt([option_type], options[:options], @api_client, api_params))
613
+ api_params.deep_merge!(server_payload)
614
+ api_params.deep_merge!(server_payload['config'])
615
+ option_type_list = option_type_list.reject {|type| type['code'] == 'computeServerType.googleLinux.googleZoneId'}
616
+ end
617
+
596
618
  # Networks
597
619
  # NOTE: You must choose subnets in the same availability zone
598
620
  if controller_provision_type && controller_provision_type['hasNetworks'] && cloud['zoneType']['code'] != 'esxi'
599
- server_payload['networkInterfaces'] = options[:networkInterfaces] || prompt_network_interfaces(cloud['id'], provision_type['id'], (resource_pool['id'] rescue nil), options)
621
+ server_payload['networkInterfaces'] = options[:networkInterfaces] || prompt_network_interfaces(cloud['id'], provision_type['id'], (resource_pool['id'] rescue nil), options.merge({:api_params => api_params}))
600
622
  end
601
623
 
602
624
  # Security Groups
@@ -605,15 +627,11 @@ class Morpheus::Cli::Clusters
605
627
  # Visibility
606
628
  server_payload['visibility'] = options[:visibility] || (Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'visibility', 'fieldLabel' => 'Visibility', 'type' => 'select', 'defaultValue' => 'private', 'required' => true, 'selectOptions' => [{'name' => 'Private', 'value' => 'private'},{'name' => 'Public', 'value' => 'public'}]}], options[:options], @api_client, {})['visibility'])
607
629
 
608
- # Options / Custom Config
609
- option_type_list = ((controller_type['optionTypes'].reject { |type| !type['enabled'] || type['fieldComponent'] } rescue []) + layout['optionTypes'] +
610
- (cluster_type['optionTypes'].reject { |type| !type['enabled'] || !type['creatable'] || type['fieldComponent'] } rescue [])).sort { |type| type['displayOrder'] }
611
-
612
- server_payload.deep_merge!(Morpheus::Cli::OptionTypes.prompt(option_type_list, options[:options], @api_client, {zoneId: cloud['id'], siteId: group['id'], layoutId: layout['id']}))
630
+ server_payload.deep_merge!(Morpheus::Cli::OptionTypes.prompt(option_type_list, options[:options], @api_client, api_params, options[:no_prompt], true))
613
631
 
614
632
  # Worker count
615
633
  default_node_count = layout['computeServers'] ? (layout['computeServers'].find {|it| it['nodeType'] == 'worker'} || {'nodeCount' => 3})['nodeCount'] : 3
616
- server_payload['nodeCount'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => "nodeCount", 'type' => 'number', 'fieldLabel' => "#{cluster_type['code'].include?('docker') ? 'Host' : 'Worker'} Count", 'required' => true, 'defaultValue' => default_node_count}], options[:options], @api_client, {}, options[:no_prompt])["nodeCount"]
634
+ server_payload['config']['nodeCount'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => "config.nodeCount", 'type' => 'number', 'fieldLabel' => "#{cluster_type['code'].include?('docker') ? 'Host' : 'Worker'} Count", 'required' => true, 'defaultValue' => default_node_count > 0 ? default_node_count : 3}], options[:options], @api_client, api_params, options[:no_prompt])['config']['nodeCount']
617
635
 
618
636
  # Create User
619
637
  if !options[:createUser].nil?
@@ -629,7 +647,7 @@ class Morpheus::Cli::Clusters
629
647
  if userGroup
630
648
  server_payload['userGroup'] = userGroup
631
649
  elsif !options[:no_prompt]
632
- userGroupId = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'userGroupId', 'fieldLabel' => 'User Group', 'type' => 'select', 'required' => false, 'optionSource' => 'userGroups'}], options[:options], @api_client, {})['userGroupId']
650
+ userGroupId = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'userGroupId', 'fieldLabel' => 'User Group', 'type' => 'select', 'required' => false, 'optionSource' => 'userGroups'}], options[:options], @api_client, api_params)['userGroupId']
633
651
 
634
652
  if userGroupId
635
653
  server_payload['userGroup'] = {'id' => userGroupId}
@@ -637,11 +655,11 @@ class Morpheus::Cli::Clusters
637
655
  end
638
656
 
639
657
  # Host / Domain
640
- server_payload['networkDomain'] = options[:domain] || Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'networkDomain', 'fieldLabel' => 'Network Domain', 'type' => 'select', 'required' => false, 'optionSource' => 'networkDomains'}], options[:options], @api_client, {})['networkDomain']
641
- server_payload['hostname'] = options[:hostname] || Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'hostname', 'fieldLabel' => 'Hostname', 'type' => 'text', 'required' => true, 'description' => 'Hostname', 'defaultValue' => resourceName}], options[:options], @api_client)['hostname']
658
+ server_payload['networkDomain'] = options[:domain] || Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'networkDomain', 'fieldLabel' => 'Network Domain', 'type' => 'select', 'required' => false, 'optionSource' => 'networkDomains'}], options[:options], @api_client, api_params)['networkDomain']
659
+ server_payload['hostname'] = options[:hostname] || Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'hostname', 'fieldLabel' => 'Hostname', 'type' => 'text', 'required' => true, 'description' => 'Hostname', 'defaultValue' => resourceName}], options[:options], @api_client, api_params)['hostname']
642
660
 
643
661
  # Workflow / Automation
644
- task_set_id = options[:taskSetId] || Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'taskSet', 'fieldLabel' => 'Workflow', 'type' => 'select', 'required' => false, 'optionSource' => 'taskSets'}], options[:options], @api_client, {'phase' => 'postProvision'})['taskSet']
662
+ task_set_id = options[:taskSetId] || Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'taskSet', 'fieldLabel' => 'Workflow', 'type' => 'select', 'required' => false, 'optionSource' => 'taskSets'}], options[:options], @api_client, api_params.merge({'phase' => 'postProvision'}))['taskSet']
645
663
 
646
664
  if !task_set_id.nil?
647
665
  server_payload['taskSet'] = {'id' => task_set_id}
@@ -1147,20 +1165,20 @@ class Morpheus::Cli::Clusters
1147
1165
  cloud_id = (default_cloud && cloud_id == default_cloud['name']) ? default_cloud['value'] : cloud_id
1148
1166
  end
1149
1167
 
1168
+ # resources (zone pools)
1169
+ cloud = @clouds_interface.get(cloud_id)['zone']
1170
+ cloud['zoneType'] = get_cloud_type(cloud['zoneType']['id'])
1171
+ group = @groups_interface.get(cluster['site']['id'])['group']
1172
+
1150
1173
  server_payload['cloud'] = {'id' => cloud_id}
1151
- service_plan = prompt_service_plan(cloud_id, server_type['provisionType'], options)
1174
+ service_plan = prompt_service_plan({zoneId: cloud_id, siteId: cluster['site']['id'], provisionTypeId: server_type['provisionType']['id'], groupTypeId: cluster_type['id'], }, options)
1152
1175
 
1153
1176
  if service_plan
1154
1177
  server_payload['plan'] = {'code' => service_plan['code'], 'options' => prompt_service_plan_options(service_plan, options)}
1155
1178
  end
1156
1179
 
1157
- # resources (zone pools)
1158
- cloud = @clouds_interface.get(cloud_id)['zone']
1159
- cloud['zoneType'] = get_cloud_type(cloud['zoneType']['id'])
1160
- group = @groups_interface.get(cluster['site']['id'])['group']
1161
-
1162
1180
  if resource_pool = prompt_resource_pool(cluster, cloud, service_plan, server_type['provisionType'], options)
1163
- server_payload['config']['resourcePool'] = resource_pool['externalId']
1181
+ server_payload['config']['resourcePoolId'] = resource_pool['id']
1164
1182
  end
1165
1183
 
1166
1184
  # Multi-disk / prompt for volumes
@@ -1181,7 +1199,7 @@ class Morpheus::Cli::Clusters
1181
1199
  server_payload['securityGroups'] = prompt_security_groups_by_cloud(cloud, provision_type, resource_pool, options)
1182
1200
 
1183
1201
  # Worker count
1184
- default_node_count = layout['computeServers'] ? (layout['computeServers'].find {|it| it['nodeType'] == 'worker'} || {'nodeCount' => 3})['nodeCount'] : 3
1202
+ default_node_count = layout['computeServers'] ? (layout['computeServers'].find {|it| it['nodeType'] == 'worker'} || {'nodeCount' => 1})['nodeCount'] : 1
1185
1203
  server_payload['nodeCount'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => "nodeCount", 'type' => 'number', 'fieldLabel' => "#{cluster_type['code'].include?('docker') ? 'Host' : 'Worker'} Count", 'required' => true, 'defaultValue' => default_node_count}], options[:options], @api_client, {}, options[:no_prompt])["nodeCount"]
1186
1204
 
1187
1205
  # Options / Custom Config
@@ -3635,8 +3653,8 @@ class Morpheus::Cli::Clusters
3635
3653
  @server_types_interface.get(val)['serverType']
3636
3654
  end
3637
3655
 
3638
- def service_plans_for_dropdown(zone_id, provision_type_id)
3639
- @servers_interface.service_plans({zoneId: zone_id, provisionTypeId: provision_type_id})['plans'] rescue []
3656
+ def service_plans_for_dropdown(api_params)
3657
+ @servers_interface.service_plans(api_params)['plans'] rescue []
3640
3658
  end
3641
3659
 
3642
3660
  def namespace_service_plans
@@ -3679,10 +3697,10 @@ class Morpheus::Cli::Clusters
3679
3697
  @groups_interface.get(group_id)['group']
3680
3698
  end
3681
3699
 
3682
- def prompt_service_plan(zone_id, provision_type, options)
3683
- available_service_plans = service_plans_for_dropdown(zone_id, provision_type['id'])
3700
+ def prompt_service_plan(api_params, options)
3701
+ available_service_plans = service_plans_for_dropdown(api_params)
3684
3702
  if available_service_plans.empty?
3685
- print_red_alert "Cloud #{zone_id} has no available plans"
3703
+ print_red_alert "Cloud #{api_params['zoneId']} has no available plans"
3686
3704
  exit 1
3687
3705
  end
3688
3706
  if options[:servicePlan]
@@ -3853,7 +3871,7 @@ class Morpheus::Cli::Clusters
3853
3871
  resource_pool = options[:resourcePool] ? find_cloud_resource_pool_by_name_or_id(cloud['id'], options[:resourcePool]) : nil
3854
3872
 
3855
3873
  if !resource_pool
3856
- resource_pool_options = @options_interface.options_for_source('zonePools', {groupId: group['id'], zoneId: cloud['id'], planId: (service_plan['id'] rescue nil)})['data'].reject { |it| it['id'].nil? && it['name'].nil? }
3874
+ resource_pool_options = @options_interface.options_for_source('zonePools', {groupId: group['id'], zoneId: cloud['id']}.merge(service_plan ? {planId: service_plan['id']} : {}))['data'].reject { |it| it['id'].nil? && it['name'].nil? }
3857
3875
 
3858
3876
  if resource_pool_options.empty?
3859
3877
  print_red_alert "Cloud #{cloud['name']} has no available resource pools"
@@ -15,9 +15,10 @@ class Morpheus::Cli::Instances
15
15
 
16
16
  set_command_name :instances
17
17
  set_command_description "View and manage instances."
18
- register_subcommands :list, :count, :get, :view, :add, :update, :remove, :cancel_removal, :logs,
18
+ register_subcommands :list, :count, :get, :view, :add, :update, :remove,
19
+ :cancel_removal, :cancel_expiration, :cancel_shutdown, :extend_expiration, :extend_shutdown,
19
20
  :history, {:'history-details' => :history_details}, {:'history-event' => :history_event_details},
20
- :stats, :stop, :start, :restart, :actions, :action, :suspend, :eject, :stop_service, :start_service, :restart_service,
21
+ :logs, :stats, :stop, :start, :restart, :actions, :action, :suspend, :eject, :stop_service, :start_service, :restart_service,
21
22
  :backup, :backups, :resize, :clone, :envs, :setenv, :delenv,
22
23
  :lock, :unlock, :clone_image,
23
24
  :security_groups, :apply_security_groups, :run_workflow, :import_snapshot, :snapshot, :snapshots,
@@ -444,7 +445,7 @@ class Morpheus::Cli::Instances
444
445
  opts.on('--refresh [SECONDS]', String, "Refresh until status is running,failed. Default interval is #{default_refresh_interval} seconds.") do |val|
445
446
  options[:refresh_interval] = val.to_s.empty? ? default_refresh_interval : val.to_f
446
447
  end
447
- build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote, :quiet])
448
+ build_standard_add_options(opts, options) #, [:options, :payload, :json, :dry_run, :remote, :quiet])
448
449
  opts.footer = "Create a new instance." + "\n" +
449
450
  "[name] is required. This is the new instance name." + "\n" +
450
451
  "The available options vary by --type."
@@ -462,33 +463,30 @@ class Morpheus::Cli::Instances
462
463
  options[:instance_name] = args[0]
463
464
  end
464
465
 
465
- begin
466
- payload = nil
467
- if options[:payload]
468
- payload = options[:payload]
469
- # support -O OPTION switch on top of --payload
470
- payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
471
- # obviously should support every option that prompt supports on top of -- payload as well
472
- # group, cloud and type for now
473
- # todo: also support :layout, service_plan, :resource_pool, etc.
474
- group = nil
475
- if options[:group]
476
- group = find_group_by_name_or_id_for_provisioning(options[:group])
477
- if group.nil?
478
- return 1, "group not found by #{options[:group]}"
479
- end
480
- #payload["siteId"] = group["id"]
481
- payload.deep_merge!({"instance" => {"site" => {"id" => group["id"]} } })
466
+ if options[:payload]
467
+ payload = options[:payload]
468
+ # support -O OPTION switch on top of --payload
469
+ payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
470
+ # obviously should support every option that prompt supports on top of -- payload as well
471
+ # group, cloud and type for now
472
+ # todo: also support :layout, service_plan, :resource_pool, etc.
473
+ group = nil
474
+ if options[:group]
475
+ group = find_group_by_name_or_id_for_provisioning(options[:group])
476
+ if group.nil?
477
+ return 1, "group not found by #{options[:group]}"
482
478
  end
483
- if options[:cloud]
484
- group_id = group ? group["id"] : ((payload["instance"] && payload["instance"]["site"].is_a?(Hash)) ? payload["instance"]["site"]["id"] : nil)
485
- cloud = find_cloud_by_name_or_id_for_provisioning(group_id, options[:cloud])
486
- if cloud.nil?
487
- return 1, "cloud not found by #{options[:cloud]}"
488
- end
489
- payload["zoneId"] = cloud["id"]
490
- payload.deep_merge!({"instance" => {"cloud" => cloud["name"] } })
479
+ payload.deep_merge!({"instance" => {"site" => {"id" => group["id"]} } })
480
+ end
481
+ if options[:cloud]
482
+ group_id = group ? group["id"] : ((payload["instance"] && payload["instance"]["site"].is_a?(Hash)) ? payload["instance"]["site"]["id"] : nil)
483
+ cloud = find_cloud_by_name_or_id_for_provisioning(group_id, options[:cloud])
484
+ if cloud.nil?
485
+ return 1, "cloud not found by #{options[:cloud]}"
491
486
  end
487
+ payload["zoneId"] = cloud["id"]
488
+ payload.deep_merge!({"instance" => {"cloud" => cloud["name"] } })
489
+ end
492
490
  if options[:cloud]
493
491
  group_id = group ? group["id"] : ((payload["instance"] && payload["instance"]["site"].is_a?(Hash)) ? payload["instance"]["site"]["id"] : nil)
494
492
  cloud = find_cloud_by_name_or_id_for_provisioning(group_id, options[:cloud])
@@ -498,96 +496,90 @@ class Morpheus::Cli::Instances
498
496
  payload["zoneId"] = cloud["id"]
499
497
  payload.deep_merge!({"instance" => {"cloud" => cloud["name"] } })
500
498
  end
501
- if options[:instance_type_code]
502
- # should just use find_instance_type_by_name_or_id
503
- # note that the api actually will match name name or code
504
- instance_type = (options[:instance_type_code].to_s =~ /\A\d{1,}\Z/) ? find_instance_type_by_id(options[:instance_type_code]) : find_instance_type_by_code(options[:instance_type_code])
505
- if instance_type.nil?
506
- return 1, "instance type not found by #{options[:cloud]}"
507
- end
508
- payload.deep_merge!({"instance" => {"type" => instance_type["code"] } })
509
- payload.deep_merge!({"instance" => {"instanceType" => {"code" => instance_type["code"]} } })
510
- end
511
-
512
- else
513
- # use active group by default
514
- options[:group] ||= @active_group_id
515
- options[:select_datastore] = true
516
- options[:name_required] = true
517
- # prompt for all the instance configuration options
518
- # this provisioning helper method handles all (most) of the parsing and prompting
519
- # and it relies on the method to exit non-zero on error, like a bad CLOUD or TYPE value
520
- payload = prompt_new_instance(options)
521
- # clean payload of empty objects
522
- # note: this is temporary and should be fixed upstream in OptionTypes.prompt()
523
- if payload['instance'].is_a?(Hash)
524
- payload['instance'].keys.each do |k|
525
- v = payload['instance'][k]
526
- payload['instance'].delete(k) if v.is_a?(Hash) && v.empty?
527
- end
528
- end
529
- if payload['config'].is_a?(Hash)
530
- payload['config'].keys.each do |k|
531
- v = payload['config'][k]
532
- payload['config'].delete(k) if v.is_a?(Hash) && v.empty?
533
- end
499
+ if options[:instance_type_code]
500
+ # should just use find_instance_type_by_name_or_id
501
+ # note that the api actually will match name name or code
502
+ instance_type = (options[:instance_type_code].to_s =~ /\A\d{1,}\Z/) ? find_instance_type_by_id(options[:instance_type_code]) : find_instance_type_by_code(options[:instance_type_code])
503
+ if instance_type.nil?
504
+ return 1, "instance type not found by #{options[:cloud]}"
534
505
  end
506
+ payload.deep_merge!({"instance" => {"type" => instance_type["code"] } })
507
+ payload.deep_merge!({"instance" => {"instanceType" => {"code" => instance_type["code"]} } })
535
508
  end
536
- payload['instance'] ||= {}
537
- if options[:instance_name]
538
- payload['instance']['name'] = options[:instance_name]
539
- end
540
- if options[:description] && !payload['instance']['description']
541
- payload['instance']['description'] = options[:description]
542
- end
543
- if options[:environment] && !payload['instance']['instanceContext']
544
- payload['instance']['instanceContext'] = options[:environment]
545
- end
546
- payload[:copies] = options[:copies] if options[:copies] && options[:copies] > 0
547
- payload[:layoutSize] = options[:layout_size] if options[:layout_size] && options[:layout_size] > 0 # aka Scale Factor
548
- payload[:createBackup] = options[:create_backup] if !options[:create_backup].nil?
549
- payload['instance']['expireDays'] = options[:expire_days] if options[:expire_days]
550
- payload['instance']['shutdownDays'] = options[:shutdown_days] if options[:shutdown_days]
551
- if options.key?(:create_user)
552
- payload['config'] ||= {}
553
- payload['config']['createUser'] = options[:create_user]
554
- end
555
- if options[:user_group_id]
556
- payload['instance']['userGroup'] = {'id' => options[:user_group_id] }
557
- end
558
- if options[:workflow_id]
559
- if options[:workflow_id].to_s =~ /\A\d{1,}\Z/
560
- payload['taskSetId'] = options[:workflow_id].to_i
561
- else
562
- payload['taskSetName'] = options[:workflow_id]
509
+ else
510
+ # use active group by default
511
+ options[:group] ||= @active_group_id
512
+ options[:select_datastore] = true
513
+ options[:name_required] = true
514
+ # prompt for all the instance configuration options
515
+ # this provisioning helper method handles all (most) of the parsing and prompting
516
+ # and it relies on the method to exit non-zero on error, like a bad CLOUD or TYPE value
517
+ payload = prompt_new_instance(options)
518
+ # clean payload of empty objects
519
+ # note: this is temporary and should be fixed upstream in OptionTypes.prompt()
520
+ if payload['instance'].is_a?(Hash)
521
+ payload['instance'].keys.each do |k|
522
+ v = payload['instance'][k]
523
+ payload['instance'].delete(k) if v.is_a?(Hash) && v.empty?
563
524
  end
564
525
  end
565
- if options[:enable_load_balancer]
566
- lb_payload = prompt_instance_load_balancer(payload['instance'], nil, options)
567
- payload.deep_merge!(lb_payload)
568
- end
569
- @instances_interface.setopts(options)
570
- if options[:dry_run]
571
- print_dry_run @instances_interface.dry.create(payload)
572
- return 0
526
+ if payload['config'].is_a?(Hash)
527
+ payload['config'].keys.each do |k|
528
+ v = payload['config'][k]
529
+ payload['config'].delete(k) if v.is_a?(Hash) && v.empty?
530
+ end
573
531
  end
532
+ end
574
533
 
575
- json_response = @instances_interface.create(payload)
576
- if options[:json]
577
- puts as_json(json_response, options)
578
- elsif !options[:quiet]
579
- instance_id = json_response["instance"]["id"]
580
- instance_name = json_response["instance"]["name"]
581
- print_green_success "Provisioning instance [#{instance_id}] #{instance_name}"
582
- # print details
583
- get_args = [instance_id] + (options[:remote] ? ["-r",options[:remote]] : []) + (options[:refresh_interval] ? ['--refresh', options[:refresh_interval].to_s] : [])
584
- get(get_args)
534
+ payload['instance'] ||= {}
535
+ if options[:instance_name]
536
+ payload['instance']['name'] = options[:instance_name]
537
+ end
538
+ if options[:description] && !payload['instance']['description']
539
+ payload['instance']['description'] = options[:description]
540
+ end
541
+ if options[:environment] && !payload['instance']['instanceContext']
542
+ payload['instance']['instanceContext'] = options[:environment]
543
+ end
544
+ payload[:copies] = options[:copies] if options[:copies] && options[:copies] > 0
545
+ payload[:layoutSize] = options[:layout_size] if options[:layout_size] && options[:layout_size] > 0 # aka Scale Factor
546
+ payload[:createBackup] = options[:create_backup] if !options[:create_backup].nil?
547
+ payload['instance']['expireDays'] = options[:expire_days] if options[:expire_days]
548
+ payload['instance']['shutdownDays'] = options[:shutdown_days] if options[:shutdown_days]
549
+ if options.key?(:create_user)
550
+ payload['config'] ||= {}
551
+ payload['config']['createUser'] = options[:create_user]
552
+ end
553
+ if options[:user_group_id]
554
+ payload['instance']['userGroup'] = {'id' => options[:user_group_id] }
555
+ end
556
+ if options[:workflow_id]
557
+ if options[:workflow_id].to_s =~ /\A\d{1,}\Z/
558
+ payload['taskSetId'] = options[:workflow_id].to_i
559
+ else
560
+ payload['taskSetName'] = options[:workflow_id]
585
561
  end
562
+ end
563
+ if options[:enable_load_balancer]
564
+ lb_payload = prompt_instance_load_balancer(payload['instance'], nil, options)
565
+ payload.deep_merge!(lb_payload)
566
+ end
567
+ @instances_interface.setopts(options)
568
+ if options[:dry_run]
569
+ print_dry_run @instances_interface.dry.create(payload)
586
570
  return 0
587
- rescue RestClient::Exception => e
588
- print_rest_exception(e, options)
589
- return 1
590
571
  end
572
+
573
+ json_response = @instances_interface.create(payload)
574
+ render_response(json_response, options, "instance") do
575
+ instance_id = json_response["instance"]["id"]
576
+ instance_name = json_response["instance"]["name"]
577
+ print_green_success "Provisioning instance [#{instance_id}] #{instance_name}"
578
+ # print details
579
+ get_args = [instance_id] + (options[:remote] ? ["-r",options[:remote]] : []) + (options[:refresh_interval] ? ['--refresh', options[:refresh_interval].to_s] : [])
580
+ get(get_args)
581
+ end
582
+ return 0, nil
591
583
  end
592
584
 
593
585
  def update(args)
@@ -1931,7 +1923,7 @@ class Morpheus::Cli::Instances
1931
1923
  opts.on('--muteMonitoring [on|off]', String, "Mute monitoring. Default is off.") do |val|
1932
1924
  params['muteMonitoring'] = val.nil? || val.to_s == 'on' || val.to_s == 'true'
1933
1925
  end
1934
- opts.add_hidden_option('muteMonitoring') if opts.is_a?(Morpheus::Cli::OptionParser)
1926
+ opts.add_hidden_option('--muteMonitoring') if opts.is_a?(Morpheus::Cli::OptionParser)
1935
1927
  build_common_options(opts, options, [:auto_confirm, :quiet, :json, :dry_run, :remote])
1936
1928
  opts.footer = "Stop an instance.\n" +
1937
1929
  "[instance] is required. This is the name or id of an instance. Supports 1-N [instance] arguments."
@@ -2059,7 +2051,7 @@ class Morpheus::Cli::Instances
2059
2051
  opts.on('--muteMonitoring [on|off]', String, "Mute monitoring. Default is on.") do |val|
2060
2052
  params['muteMonitoring'] = val.nil? || val.to_s == 'on' || val.to_s == 'true'
2061
2053
  end
2062
- opts.add_hidden_option('muteMonitoring') if opts.is_a?(Morpheus::Cli::OptionParser)
2054
+ opts.add_hidden_option('--muteMonitoring') if opts.is_a?(Morpheus::Cli::OptionParser)
2063
2055
  build_common_options(opts, options, [:auto_confirm, :quiet, :json, :dry_run, :remote])
2064
2056
  opts.footer = "Restart an instance.\n" +
2065
2057
  "[instance] is required. This is the name or id of an instance. Supports 1-N [instance] arguments."
@@ -2127,7 +2119,7 @@ class Morpheus::Cli::Instances
2127
2119
  opts.on('--muteMonitoring [on|off]', String, "Mute monitoring. Default is on.") do |val|
2128
2120
  params['muteMonitoring'] = val.nil? || val.to_s == 'on' || val.to_s == 'true'
2129
2121
  end
2130
- opts.add_hidden_option('muteMonitoring')
2122
+ opts.add_hidden_option('--muteMonitoring')
2131
2123
  opts.on('--server [on|off]', String, "Suspend instance server. Default is off.") do |val|
2132
2124
  params['server'] = val.nil? || val.to_s == 'on' || val.to_s == 'true'
2133
2125
  end
@@ -2233,7 +2225,7 @@ class Morpheus::Cli::Instances
2233
2225
  opts.on('--muteMonitoring [on|off]', String, "Mute monitoring. Default is off.") do |val|
2234
2226
  params['muteMonitoring'] = val.nil? || val.to_s == 'on' || val.to_s == 'true'
2235
2227
  end
2236
- opts.add_hidden_option('muteMonitoring') if opts.is_a?(Morpheus::Cli::OptionParser)
2228
+ opts.add_hidden_option('--muteMonitoring') if opts.is_a?(Morpheus::Cli::OptionParser)
2237
2229
  build_common_options(opts, options, [:auto_confirm, :quiet, :json, :dry_run, :remote])
2238
2230
  opts.footer = "Stop service on an instance.\n" +
2239
2231
  "[instance] is required. This is the name or id of an instance. Supports 1-N [instance] arguments."
@@ -2361,7 +2353,7 @@ class Morpheus::Cli::Instances
2361
2353
  opts.on('--muteMonitoring [on|off]', String, "Mute monitoring. Default is on.") do |val|
2362
2354
  params['muteMonitoring'] = val.nil? || val.to_s == 'on' || val.to_s == 'true'
2363
2355
  end
2364
- opts.add_hidden_option('muteMonitoring')
2356
+ opts.add_hidden_option('--muteMonitoring')
2365
2357
  build_common_options(opts, options, [:auto_confirm, :quiet, :json, :dry_run, :remote])
2366
2358
  opts.footer = "Restart service on an instance.\n" +
2367
2359
  "[instance] is required. This is the name or id of an instance. Supports 1-N [instance] arguments."
@@ -2565,46 +2557,50 @@ class Morpheus::Cli::Instances
2565
2557
  options = {}
2566
2558
  optparse = Morpheus::Cli::OptionParser.new do |opts|
2567
2559
  opts.banner = subcommand_usage("[instance]")
2568
- build_common_options(opts, options, [:options, :json, :dry_run, :remote])
2560
+ build_standard_update_options(opts, options)
2569
2561
  end
2570
2562
  optparse.parse!(args)
2571
- if args.count < 1
2572
- puts optparse
2573
- exit 1
2574
- end
2563
+ verify_args!(args:args, optparse:optparse, count:1)
2575
2564
  connect(options)
2576
- begin
2577
- instance = find_instance_by_name_or_id(args[0])
2578
-
2579
- group_id = instance['group']['id']
2580
- cloud_id = instance['cloud']['id']
2581
- layout_id = instance['layout']['id']
2582
-
2583
- plan_id = instance['plan']['id']
2565
+ instance = find_instance_by_name_or_id(args[0])
2566
+ return 1, "instance not found" if instance.nil?
2567
+
2568
+ payload = {}
2569
+ if options[:payload]
2570
+ payload = options[:payload]
2571
+ payload.deep_merge!(parse_passed_options(options))
2572
+ else
2584
2573
  payload = {
2585
- :instance => {:id => instance["id"]}
2574
+ "instance" => {:id => instance["id"]}
2586
2575
  }
2576
+ payload.deep_merge!(parse_passed_options(options))
2587
2577
 
2588
2578
  # avoid 500 error
2589
2579
  # payload[:servicePlanOptions] = {}
2590
2580
 
2591
2581
  puts "\nDue to limitations by most Guest Operating Systems, Disk sizes can only be expanded and not reduced.\nIf a smaller plan is selected, memory and CPU (if relevant) will be reduced but storage will not.\n\n"
2592
2582
 
2583
+ group_id = instance['group']['id']
2584
+ cloud_id = instance['cloud']['id']
2585
+ layout_id = instance['layout']['id']
2586
+ plan_id = instance['plan']['id']
2587
+ current_plan_name = instance['plan']['name']
2593
2588
  # prompt for service plan
2594
2589
  service_plans_json = @instances_interface.service_plans({zoneId: cloud_id, siteId: group_id, layoutId: layout_id})
2595
2590
  service_plans = service_plans_json["plans"]
2596
2591
  service_plans_dropdown = service_plans.collect {|sp| {'name' => sp["name"], 'value' => sp["id"]} } # already sorted
2597
2592
  service_plans_dropdown.each do |plan|
2598
- if plan['value'] && plan['value'].to_i == plan_id.to_i
2599
- plan['name'] = "#{plan['name']} (current)"
2600
- end
2593
+ # if plan['value'] && plan['value'].to_i == plan_id.to_i
2594
+ # plan['name'] = "#{plan['name']} (current)"
2595
+ # current_plan_name = plan['name']
2596
+ # end
2601
2597
  end
2602
- plan_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'servicePlan', 'type' => 'select', 'fieldLabel' => 'Plan', 'selectOptions' => service_plans_dropdown, 'required' => true, 'description' => 'Choose the appropriately sized plan for this instance'}],options[:options])
2598
+ plan_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'servicePlan', 'type' => 'select', 'fieldLabel' => 'Plan', 'selectOptions' => service_plans_dropdown, 'required' => true, 'defaultValue' => current_plan_name, 'description' => 'Choose the appropriately sized plan for this instance'}],options[:options])
2603
2599
  service_plan = service_plans.find {|sp| sp["id"] == plan_prompt['servicePlan'].to_i }
2604
2600
  new_plan_id = service_plan["id"]
2605
2601
  #payload[:servicePlan] = new_plan_id # ew, this api uses servicePlanId instead
2606
2602
  #payload[:servicePlanId] = new_plan_id
2607
- payload[:instance][:plan] = {id: service_plan["id"]}
2603
+ payload["instance"]["plan"] = {"id" => service_plan["id"]}
2608
2604
 
2609
2605
  volumes_response = @instances_interface.volumes(instance['id'])
2610
2606
  current_volumes = volumes_response['volumes'].sort {|x,y| x['displayOrder'] <=> y['displayOrder'] }
@@ -2612,29 +2608,27 @@ class Morpheus::Cli::Instances
2612
2608
  # prompt for volumes
2613
2609
  volumes = prompt_resize_volumes(current_volumes, service_plan, options)
2614
2610
  if !volumes.empty?
2615
- payload[:volumes] = volumes
2611
+ payload["volumes"] = volumes
2616
2612
  end
2617
2613
 
2618
2614
  # only amazon supports this option
2619
2615
  # for now, always do this
2620
- payload[:deleteOriginalVolumes] = true
2621
- @instances_interface.setopts(options)
2622
- if options[:dry_run]
2623
- print_dry_run @instances_interface.dry.resize(instance['id'], payload)
2624
- return
2625
- end
2626
- json_response = @instances_interface.resize(instance['id'], payload)
2627
- if options[:json]
2628
- puts as_json(json_response, options)
2629
- return 0
2630
- else
2631
- print_green_success "Resizing instance #{instance['name']}"
2632
- #list([])
2633
- end
2634
- rescue RestClient::Exception => e
2635
- print_rest_exception(e, options)
2636
- exit 1
2616
+ payload["deleteOriginalVolumes"] = true
2617
+ end
2618
+ payload.delete("rootVolume")
2619
+ (1..20).each {|i| payload.delete("dataVolume#{i}") }
2620
+ @instances_interface.setopts(options)
2621
+ if options[:dry_run]
2622
+ print_dry_run @instances_interface.dry.resize(instance['id'], payload)
2623
+ return
2637
2624
  end
2625
+ json_response = @instances_interface.resize(instance['id'], payload)
2626
+ render_response(json_response, options, 'snapshots') do
2627
+ print_green_success "Resizing instance #{instance['name']}"
2628
+ end
2629
+ return 0, nil
2630
+
2631
+
2638
2632
  end
2639
2633
 
2640
2634
  def backup(args)
@@ -2783,34 +2777,158 @@ EOT
2783
2777
 
2784
2778
  def cancel_removal(args)
2785
2779
  options = {}
2780
+ params = {}
2786
2781
  optparse = Morpheus::Cli::OptionParser.new do |opts|
2787
2782
  opts.banner = subcommand_usage("[instance]")
2788
- build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
2783
+ build_standard_update_options(opts, options)
2784
+ opts.footer = <<-EOT
2785
+ Cancel removal of an instance.
2786
+ This is a way to undo delete of an instance still pending removal.
2787
+ [instance] is required. This is the name or id of an instance
2788
+ EOT
2789
2789
  end
2790
2790
  optparse.parse!(args)
2791
- if args.count < 1
2792
- puts optparse
2793
- exit 1
2791
+ verify_args!(args:args, optparse:optparse, count:1)
2792
+ connect(options)
2793
+ params.merge!(parse_query_options(options))
2794
+ payload = options[:payload] || {}
2795
+ payload.deep_merge!(parse_passed_options(options))
2796
+ instance = find_instance_by_name_or_id(args[0])
2797
+ @instances_interface.setopts(options)
2798
+ if options[:dry_run]
2799
+ print_dry_run @instances_interface.dry.cancel_removal(instance['id'], params, payload)
2800
+ return
2801
+ end
2802
+ json_response = @instances_interface.cancel_removal(instance['id'], params, payload)
2803
+ render_response(json_response, options) do
2804
+ print_green_success "Canceled removal for instance #{instance['name']} ..."
2805
+ get([instance['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
2794
2806
  end
2807
+ return 0, nil
2808
+ end
2809
+
2810
+ def cancel_expiration(args)
2811
+ options = {}
2812
+ params = {}
2813
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
2814
+ opts.banner = subcommand_usage("[instance]")
2815
+ build_standard_update_options(opts, options, [:query]) # query params instead of p
2816
+ opts.footer = <<-EOT
2817
+ Cancel expiration of an instance.
2818
+ [instance] is required. This is the name or id of an instance
2819
+ EOT
2820
+ end
2821
+ optparse.parse!(args)
2822
+ verify_args!(args:args, optparse:optparse, count:1)
2795
2823
  connect(options)
2796
- begin
2797
- instance = find_instance_by_name_or_id(args[0])
2798
- @instances_interface.setopts(options)
2799
- if options[:dry_run]
2800
- print_dry_run @instances_interface.dry.cancel_removal(instance['id'])
2801
- return
2802
- end
2803
- json_response = @instances_interface.cancel_removal(instance['id'])
2804
- if options[:json]
2805
- print as_json(json_response, options), "\n"
2806
- return
2807
- elsif !options[:quiet]
2808
- get([instance['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
2809
- end
2810
- rescue RestClient::Exception => e
2811
- print_rest_exception(e, options)
2812
- exit 1
2824
+ params.merge!(parse_query_options(options))
2825
+ payload = options[:payload] || {}
2826
+ payload.deep_merge!(parse_passed_options(options))
2827
+ instance = find_instance_by_name_or_id(args[0])
2828
+ @instances_interface.setopts(options)
2829
+ if options[:dry_run]
2830
+ print_dry_run @instances_interface.dry.cancel_expiration(instance['id'], params, payload)
2831
+ return
2832
+ end
2833
+ json_response = @instances_interface.cancel_expiration(instance['id'], params, payload)
2834
+ render_response(json_response, options) do
2835
+ print_green_success "Canceled expiration for instance #{instance['name']} ..."
2836
+ get([instance['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
2837
+ end
2838
+ return 0, nil
2839
+ end
2840
+
2841
+ def cancel_shutdown(args)
2842
+ options = {}
2843
+ params = {}
2844
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
2845
+ opts.banner = subcommand_usage("[instance]")
2846
+ build_standard_update_options(opts, options, [:query]) # query params instead of p
2847
+ opts.footer = <<-EOT
2848
+ Cancel shutdown for an instance.
2849
+ [instance] is required. This is the name or id of an instance
2850
+ EOT
2813
2851
  end
2852
+ optparse.parse!(args)
2853
+ verify_args!(args:args, optparse:optparse, count:1)
2854
+ connect(options)
2855
+ params.merge!(parse_query_options(options))
2856
+ payload = options[:payload] || {}
2857
+ payload.deep_merge!(parse_passed_options(options))
2858
+ instance = find_instance_by_name_or_id(args[0])
2859
+ @instances_interface.setopts(options)
2860
+ if options[:dry_run]
2861
+ print_dry_run @instances_interface.dry.cancel_shutdown(instance['id'], params, payload)
2862
+ return
2863
+ end
2864
+ json_response = @instances_interface.cancel_shutdown(instance['id'], params, payload)
2865
+ render_response(json_response, options) do
2866
+ print_green_success "Canceled shutdown for instance #{instance['name']} ..."
2867
+ get([instance['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
2868
+ end
2869
+ return 0, nil
2870
+ end
2871
+
2872
+ def extend_expiration(args)
2873
+ options = {}
2874
+ params = {}
2875
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
2876
+ opts.banner = subcommand_usage("[instance]")
2877
+ build_standard_update_options(opts, options, [:query]) # query params instead of p
2878
+ opts.footer = <<-EOT
2879
+ Extend expiration for an instance.
2880
+ [instance] is required. This is the name or id of an instance
2881
+ EOT
2882
+ end
2883
+ optparse.parse!(args)
2884
+ verify_args!(args:args, optparse:optparse, count:1)
2885
+ connect(options)
2886
+ params.merge!(parse_query_options(options))
2887
+ payload = options[:payload] || {}
2888
+ payload.deep_merge!(parse_passed_options(options))
2889
+ instance = find_instance_by_name_or_id(args[0])
2890
+ @instances_interface.setopts(options)
2891
+ if options[:dry_run]
2892
+ print_dry_run @instances_interface.dry.extend_expiration(instance['id'], params, payload)
2893
+ return
2894
+ end
2895
+ json_response = @instances_interface.extend_expiration(instance['id'], params, payload)
2896
+ render_response(json_response, options) do
2897
+ print_green_success "Extended expiration for instance #{instance['name']} ..."
2898
+ get([instance['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
2899
+ end
2900
+ return 0, nil
2901
+ end
2902
+
2903
+ def extend_shutdown(args)
2904
+ options = {}
2905
+ params = {}
2906
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
2907
+ opts.banner = subcommand_usage("[instance]")
2908
+ build_standard_update_options(opts, options, [:query]) # query params instead of p
2909
+ opts.footer = <<-EOT
2910
+ Extend shutdown for an instance.
2911
+ [instance] is required. This is the name or id of an instance
2912
+ EOT
2913
+ end
2914
+ optparse.parse!(args)
2915
+ verify_args!(args:args, optparse:optparse, count:1)
2916
+ connect(options)
2917
+ params.merge!(parse_query_options(options))
2918
+ payload = options[:payload] || {}
2919
+ payload.deep_merge!(parse_passed_options(options))
2920
+ instance = find_instance_by_name_or_id(args[0])
2921
+ @instances_interface.setopts(options)
2922
+ if options[:dry_run]
2923
+ print_dry_run @instances_interface.dry.extend_shutdown(instance['id'], params, payload)
2924
+ return
2925
+ end
2926
+ json_response = @instances_interface.extend_shutdown(instance['id'], params, payload)
2927
+ render_response(json_response, options) do
2928
+ print_green_success "Extended shutdown for instance #{instance['name']} ..."
2929
+ get([instance['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
2930
+ end
2931
+ return 0, nil
2814
2932
  end
2815
2933
 
2816
2934
  def firewall_disable(args)
@@ -3615,7 +3733,7 @@ EOT
3615
3733
  opts.on('--process-id ID', String, "Display details about a specfic event." ) do |val|
3616
3734
  options[:process_id] = val
3617
3735
  end
3618
- opts.add_hidden_option('process-id')
3736
+ opts.add_hidden_option('--process-id')
3619
3737
  build_common_options(opts, options, [:query, :json, :yaml, :csv, :fields, :dry_run, :remote])
3620
3738
  opts.footer = "Display history details for a specific process.\n" +
3621
3739
  "[instance] is required. This is the name or id of an instance.\n" +
@@ -3715,7 +3833,7 @@ EOT
3715
3833
  opts.on('--event-id ID', String, "Display details about a specfic event." ) do |val|
3716
3834
  options[:event_id] = val
3717
3835
  end
3718
- opts.add_hidden_option('event-id')
3836
+ opts.add_hidden_option('--event-id')
3719
3837
  build_common_options(opts, options, [:query, :json, :yaml, :csv, :fields, :dry_run, :remote])
3720
3838
  opts.footer = "Display history details for a specific process event.\n" +
3721
3839
  "[instance] is required. This is the name or id of an instance.\n" +