morpheus-cli 5.3.2.3 → 5.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/lib/morpheus/api/instances_interface.rb +18 -5
- data/lib/morpheus/api/virtual_images_interface.rb +23 -2
- data/lib/morpheus/cli/apps.rb +3 -2
- data/lib/morpheus/cli/cli_command.rb +12 -5
- data/lib/morpheus/cli/cli_registry.rb +55 -2
- data/lib/morpheus/cli/cloud_resource_pools_command.rb +169 -133
- data/lib/morpheus/cli/clusters.rb +51 -33
- data/lib/morpheus/cli/instances.rb +253 -137
- data/lib/morpheus/cli/invoices_command.rb +79 -99
- data/lib/morpheus/cli/library_cluster_layouts_command.rb +20 -0
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +120 -94
- data/lib/morpheus/cli/monitoring_checks_command.rb +2 -0
- data/lib/morpheus/cli/networks_command.rb +1 -1
- data/lib/morpheus/cli/option_parser.rb +25 -17
- data/lib/morpheus/cli/option_types.rb +22 -15
- data/lib/morpheus/cli/vdi_pools_command.rb +4 -1
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/virtual_images.rb +249 -29
- data/morpheus-cli.gemspec +1 -1
- metadata +4 -4
@@ -564,13 +564,10 @@ class Morpheus::Cli::Clusters
|
|
564
564
|
|
565
565
|
cluster_payload['layout'] = {id: layout['id']}
|
566
566
|
|
567
|
-
#
|
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
|
-
|
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,
|
585
|
-
|
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,
|
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
|
-
|
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,
|
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,
|
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,
|
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']['
|
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' =>
|
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(
|
3639
|
-
@servers_interface.service_plans(
|
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(
|
3683
|
-
available_service_plans = service_plans_for_dropdown(
|
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 #{
|
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']
|
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,
|
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
|
-
|
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
|
-
|
466
|
-
payload =
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
group =
|
475
|
-
if
|
476
|
-
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
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
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
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
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
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
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
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
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
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
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."
|
@@ -2785,34 +2777,158 @@ EOT
|
|
2785
2777
|
|
2786
2778
|
def cancel_removal(args)
|
2787
2779
|
options = {}
|
2780
|
+
params = {}
|
2788
2781
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
2789
2782
|
opts.banner = subcommand_usage("[instance]")
|
2790
|
-
|
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
|
2791
2789
|
end
|
2792
2790
|
optparse.parse!(args)
|
2793
|
-
|
2794
|
-
|
2795
|
-
|
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]] : []))
|
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
|
2796
2820
|
end
|
2821
|
+
optparse.parse!(args)
|
2822
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
2797
2823
|
connect(options)
|
2798
|
-
|
2799
|
-
|
2800
|
-
|
2801
|
-
|
2802
|
-
|
2803
|
-
|
2804
|
-
|
2805
|
-
|
2806
|
-
if options[:json]
|
2807
|
-
print as_json(json_response, options), "\n"
|
2808
|
-
return
|
2809
|
-
elsif !options[:quiet]
|
2810
|
-
get([instance['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
|
2811
|
-
end
|
2812
|
-
rescue RestClient::Exception => e
|
2813
|
-
print_rest_exception(e, options)
|
2814
|
-
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
|
2815
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
|
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
|
2816
2932
|
end
|
2817
2933
|
|
2818
2934
|
def firewall_disable(args)
|
@@ -3617,7 +3733,7 @@ EOT
|
|
3617
3733
|
opts.on('--process-id ID', String, "Display details about a specfic event." ) do |val|
|
3618
3734
|
options[:process_id] = val
|
3619
3735
|
end
|
3620
|
-
opts.add_hidden_option('process-id')
|
3736
|
+
opts.add_hidden_option('--process-id')
|
3621
3737
|
build_common_options(opts, options, [:query, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
3622
3738
|
opts.footer = "Display history details for a specific process.\n" +
|
3623
3739
|
"[instance] is required. This is the name or id of an instance.\n" +
|
@@ -3717,7 +3833,7 @@ EOT
|
|
3717
3833
|
opts.on('--event-id ID', String, "Display details about a specfic event." ) do |val|
|
3718
3834
|
options[:event_id] = val
|
3719
3835
|
end
|
3720
|
-
opts.add_hidden_option('event-id')
|
3836
|
+
opts.add_hidden_option('--event-id')
|
3721
3837
|
build_common_options(opts, options, [:query, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
3722
3838
|
opts.footer = "Display history details for a specific process event.\n" +
|
3723
3839
|
"[instance] is required. This is the name or id of an instance.\n" +
|