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.
@@ -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."
@@ -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
- 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
2791
2789
  end
2792
2790
  optparse.parse!(args)
2793
- if args.count < 1
2794
- puts optparse
2795
- 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]] : []))
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
- begin
2799
- instance = find_instance_by_name_or_id(args[0])
2800
- @instances_interface.setopts(options)
2801
- if options[:dry_run]
2802
- print_dry_run @instances_interface.dry.cancel_removal(instance['id'])
2803
- return
2804
- end
2805
- json_response = @instances_interface.cancel_removal(instance['id'])
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" +