morpheus-cli 5.5.2.1 → 5.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/Dockerfile +1 -1
  4. data/README.md +57 -4
  5. data/Rakefile +9 -0
  6. data/bin/morpheus +4 -4
  7. data/lib/morpheus/api/api_client.rb +8 -2
  8. data/lib/morpheus/api/archive_buckets_interface.rb +1 -1
  9. data/lib/morpheus/api/archive_files_interface.rb +3 -3
  10. data/lib/morpheus/api/clients_interface.rb +2 -2
  11. data/lib/morpheus/api/clusters_interface.rb +8 -1
  12. data/lib/morpheus/api/containers_interface.rb +29 -16
  13. data/lib/morpheus/api/custom_instance_types_interface.rb +0 -2
  14. data/lib/morpheus/api/doc_interface.rb +8 -6
  15. data/lib/morpheus/api/file_copy_request_interface.rb +1 -1
  16. data/lib/morpheus/api/health_interface.rb +1 -1
  17. data/lib/morpheus/api/image_builder_interface.rb +3 -3
  18. data/lib/morpheus/api/instances_interface.rb +25 -0
  19. data/lib/morpheus/api/logs_interface.rb +2 -4
  20. data/lib/morpheus/api/monitoring_interface.rb +6 -6
  21. data/lib/morpheus/api/packages_interface.rb +1 -1
  22. data/lib/morpheus/api/reports_interface.rb +1 -1
  23. data/lib/morpheus/api/servers_interface.rb +9 -1
  24. data/lib/morpheus/api/storage_providers_interface.rb +2 -2
  25. data/lib/morpheus/api/virtual_images_interface.rb +1 -1
  26. data/lib/morpheus/api.rb +2 -0
  27. data/lib/morpheus/benchmarking.rb +1 -1
  28. data/lib/morpheus/cli/cli_command.rb +69 -36
  29. data/lib/morpheus/cli/cli_registry.rb +19 -10
  30. data/lib/morpheus/cli/commands/access_token_command.rb +1 -1
  31. data/lib/morpheus/cli/commands/apps.rb +1 -1
  32. data/lib/morpheus/cli/commands/archives_command.rb +25 -33
  33. data/lib/morpheus/cli/commands/blueprints_command.rb +10 -21
  34. data/lib/morpheus/cli/commands/boot_scripts_command.rb +2 -2
  35. data/lib/morpheus/cli/commands/cat_command.rb +1 -1
  36. data/lib/morpheus/cli/commands/catalog_item_types_command.rb +12 -12
  37. data/lib/morpheus/cli/commands/clouds.rb +3 -3
  38. data/lib/morpheus/cli/commands/clusters.rb +154 -3
  39. data/lib/morpheus/cli/commands/containers_command.rb +398 -253
  40. data/lib/morpheus/cli/commands/deployments.rb +1 -1
  41. data/lib/morpheus/cli/commands/deploys.rb +9 -9
  42. data/lib/morpheus/cli/commands/doc.rb +15 -16
  43. data/lib/morpheus/cli/commands/execution_request_command.rb +2 -2
  44. data/lib/morpheus/cli/commands/file_copy_request_command.rb +5 -5
  45. data/lib/morpheus/cli/commands/groups.rb +2 -2
  46. data/lib/morpheus/cli/commands/health_command.rb +4 -4
  47. data/lib/morpheus/cli/commands/hosts.rb +43 -5
  48. data/lib/morpheus/cli/commands/image_builder_command.rb +1 -1
  49. data/lib/morpheus/cli/commands/instances.rb +419 -148
  50. data/lib/morpheus/cli/commands/integrations_command.rb +22 -20
  51. data/lib/morpheus/cli/commands/key_pairs.rb +2 -2
  52. data/lib/morpheus/cli/commands/library_container_scripts_command.rb +2 -2
  53. data/lib/morpheus/cli/commands/library_container_templates_command.rb +2 -2
  54. data/lib/morpheus/cli/commands/library_instance_types_command.rb +3 -3
  55. data/lib/morpheus/cli/commands/library_spec_templates_command.rb +2 -2
  56. data/lib/morpheus/cli/commands/login.rb +1 -1
  57. data/lib/morpheus/cli/commands/man_command.rb +32 -18
  58. data/lib/morpheus/cli/commands/packages_command.rb +11 -11
  59. data/lib/morpheus/cli/commands/plugins.rb +1 -1
  60. data/lib/morpheus/cli/commands/policies_command.rb +4 -4
  61. data/lib/morpheus/cli/commands/preseed_scripts_command.rb +2 -2
  62. data/lib/morpheus/cli/commands/remote.rb +1 -1
  63. data/lib/morpheus/cli/commands/reports_command.rb +3 -3
  64. data/lib/morpheus/cli/commands/roles.rb +6 -3
  65. data/lib/morpheus/cli/commands/security_groups.rb +1 -1
  66. data/lib/morpheus/cli/commands/shell.rb +40 -62
  67. data/lib/morpheus/cli/commands/snapshots.rb +3 -5
  68. data/lib/morpheus/cli/commands/source_command.rb +8 -16
  69. data/lib/morpheus/cli/commands/storage_providers_command.rb +7 -7
  70. data/lib/morpheus/cli/commands/tasks.rb +2 -2
  71. data/lib/morpheus/cli/commands/vdi_pools_command.rb +6 -6
  72. data/lib/morpheus/cli/commands/view.rb +5 -1
  73. data/lib/morpheus/cli/commands/whitelabel_settings_command.rb +4 -4
  74. data/lib/morpheus/cli/commands/whoami.rb +2 -2
  75. data/lib/morpheus/cli/credentials.rb +30 -8
  76. data/lib/morpheus/cli/dot_file.rb +8 -15
  77. data/lib/morpheus/cli/error_handler.rb +16 -0
  78. data/lib/morpheus/cli/errors.rb +8 -1
  79. data/lib/morpheus/cli/mixins/print_helper.rb +17 -13
  80. data/lib/morpheus/cli/mixins/rest_command.rb +18 -18
  81. data/lib/morpheus/cli/mixins/secondary_rest_command.rb +12 -12
  82. data/lib/morpheus/cli/option_parser.rb +5 -1
  83. data/lib/morpheus/cli/option_types.rb +59 -12
  84. data/lib/morpheus/cli/version.rb +1 -1
  85. data/lib/morpheus/cli.rb +26 -16
  86. data/lib/morpheus/ext/rest_client.rb +3 -2
  87. data/lib/morpheus/formatters.rb +1 -1
  88. data/lib/morpheus/logging.rb +4 -4
  89. data/lib/morpheus/morpkg.rb +4 -4
  90. data/lib/morpheus/rest_client.rb +2 -2
  91. data/lib/morpheus/routes.rb +2 -2
  92. data/lib/morpheus/terminal.rb +65 -16
  93. data/lib/morpheus.rb +1 -1
  94. data/morpheus-cli.gemspec +1 -0
  95. data/test/api/containers_interface_test.rb +68 -0
  96. data/test/api/doc_interface_test.rb +35 -0
  97. data/test/api/instances_interface_test.rb +22 -0
  98. data/test/api/whoami_interface_test.rb +14 -0
  99. data/test/cli/access_token_test.rb +36 -0
  100. data/test/cli/auth_test.rb +82 -0
  101. data/test/cli/cli_test.rb +48 -0
  102. data/test/cli/containers_test.rb +92 -0
  103. data/test/cli/doc_test.rb +35 -0
  104. data/test/cli/help_test.rb +25 -0
  105. data/test/cli/instances_test.rb +36 -0
  106. data/test/cli/man_test.rb +14 -0
  107. data/test/cli/remote_test.rb +89 -0
  108. data/test/cli/roles_test.rb +34 -0
  109. data/test/cli/shell_test.rb +81 -0
  110. data/test/cli/version_test.rb +23 -0
  111. data/test/cli/view_test.rb +55 -0
  112. data/test/cli/whoami_test.rb +17 -0
  113. data/test/morpheus_test.rb +16 -0
  114. data/test/test_case.rb +338 -0
  115. data/test/test_config.rb +137 -0
  116. data/test/test_data_helper.rb +97 -0
  117. metadata +61 -3
@@ -21,7 +21,8 @@ class Morpheus::Cli::Instances
21
21
  :security_groups, :apply_security_groups, :run_workflow,
22
22
  :import_snapshot, :snapshot, :snapshots, :revert_to_snapshot, :remove_all_snapshots, :remove_all_container_snapshots, :create_linked_clone,
23
23
  :console, :status_check, {:containers => :list_containers},
24
- :scaling, {:'scaling-update' => :scaling_update},
24
+ :scaling, :update_scaling, {:'scaling-update' => :scaling_update},
25
+ {:'schedules' => :list_schedules}, :get_schedule, :add_schedule, :update_schedule, :remove_schedule, # these are scaling schedules..
25
26
  :wiki, :update_wiki,
26
27
  :update_network_label,
27
28
  {:exec => :execution_request},
@@ -34,6 +35,7 @@ class Morpheus::Cli::Instances
34
35
 
35
36
  # hide these for now
36
37
  set_subcommands_hidden :prepare_apply
38
+ set_subcommands_hidden :'scaling-update' # renamed to upate-scaling
37
39
 
38
40
  def initialize()
39
41
  #@appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
@@ -832,7 +834,7 @@ class Morpheus::Cli::Instances
832
834
  build_option_type_options(opts, options, update_wiki_page_option_types)
833
835
  opts.on('--file FILE', "File containing the wiki content. This can be used instead of --content") do |filename|
834
836
  full_filename = File.expand_path(filename)
835
- if File.exists?(full_filename)
837
+ if File.exist?(full_filename)
836
838
  params['content'] = File.read(full_filename)
837
839
  else
838
840
  print_red_alert "File not found: #{full_filename}"
@@ -3767,7 +3769,7 @@ EOT
3767
3769
  end
3768
3770
 
3769
3771
  instance_threshold = json_response['instanceThreshold']
3770
-
3772
+ instance_schedules = json_response['instanceSchedules']
3771
3773
  title = "Instance Scaling: [#{instance['id']}] #{instance['name']} (#{instance['instanceType']['name']})"
3772
3774
  print_h1 title, [], options
3773
3775
  if instance_threshold.empty?
@@ -3776,6 +3778,11 @@ EOT
3776
3778
  # print_h1 "Threshold Settings", [], options
3777
3779
  print cyan
3778
3780
  print_instance_threshold_description_list(instance_threshold)
3781
+
3782
+ if instance_schedules && instance_schedules.size > 0
3783
+ print_h2 "Instance Schedules"
3784
+ print as_pretty_table(instance_schedules, instance_schedule_list_column_definitions(options).upcase_keys!, options)
3785
+ end
3779
3786
  end
3780
3787
  print reset, "\n"
3781
3788
  return 0
@@ -3783,124 +3790,323 @@ EOT
3783
3790
  end
3784
3791
 
3785
3792
  def scaling_update(args)
3786
- usage = "Usage: morpheus instances scaling-update [instance] [options]"
3793
+ print_error "#{yellow}DEPRECATION WARNING: `instances scaling-update` has been renamed to `instances update-scaling`. Please use `instances update-scaling` instead.#{reset}\n"
3794
+ update_scaling(args)
3795
+ end
3796
+
3797
+ def update_scaling(args)
3787
3798
  options = {}
3788
3799
  optparse = Morpheus::Cli::OptionParser.new do|opts|
3789
3800
  opts.banner = subcommand_usage("[instance]")
3790
- build_option_type_options(opts, options, instance_scaling_option_types(nil))
3791
- build_common_options(opts, options, [:options, :json, :dry_run, :remote])
3792
- opts.footer = "Update scaling threshold information for an instance."
3801
+ build_option_type_options(opts, options, update_instance_scaling_option_types)
3802
+ build_option_type_options(opts, options, instance_threshold_option_types)
3803
+ build_standard_update_options(opts, options)
3804
+ opts.footer = "Update scaling threshold settings for an instance."
3793
3805
  end
3794
3806
  optparse.parse!(args)
3795
- # if args.count < 1
3796
- if args.count != 1
3797
- print_error Morpheus::Terminal.angry_prompt
3798
- puts_error "#{command_name} scaling-update requires only one argument [id or name]\n#{optparse}"
3799
- return 1
3800
- end
3807
+ verify_args!(args:args, optparse:optparse, count:1)
3801
3808
  connect(options)
3802
-
3803
- begin
3804
-
3805
- instance = find_instance_by_name_or_id(args[0])
3806
- return 1 if instance.nil?
3807
- instance_threshold = @instances_interface.threshold(instance['id'])['instanceThreshold'] || {}
3808
- my_option_types = instance_scaling_option_types(instance)
3809
-
3810
- # preserve current values by setting the prompt options defaultValue attribute
3811
- # note: checkbox type converts true,false to 'on','off'
3812
- my_option_types.each do |opt|
3813
- field_key = opt['fieldName'] # .sub('instanceThreshold.', '')
3814
- if instance_threshold[field_key] != nil
3815
- opt['defaultValue'] = instance_threshold[field_key]
3816
- end
3817
- end
3818
-
3819
- # params = Morpheus::Cli::OptionTypes.prompt(my_option_types, options[:options], @api_client, {})
3820
-
3821
- # ok, gotta split these inputs into sections with conditional logic
3809
+ # load objects
3810
+ instance = find_instance_by_name_or_id(args[0])
3811
+ return 1 if instance.nil?
3812
+ instance_threshold = @instances_interface.threshold(instance['id'])['instanceThreshold'] || {}
3813
+ # construct payload
3814
+ object_key = 'instanceThreshold'
3815
+ payload = parse_payload(options, object_key)
3816
+ if !payload
3817
+ # payload = {object_key => {}}
3818
+ payload = {object_key => parse_passed_options(options, exclude: ['sourceThresholdId'])}
3822
3819
  params = {}
3823
-
3824
- option_types_group = my_option_types.select {|opt| ['autoUp', 'autoDown'].include?(opt['fieldName']) }
3825
- params.merge! Morpheus::Cli::OptionTypes.prompt(option_types_group, options[:options], @api_client, {})
3826
-
3827
- option_types_group = my_option_types.select {|opt| ['zoneId'].include?(opt['fieldName']) }
3828
- params.merge! Morpheus::Cli::OptionTypes.prompt(option_types_group, options[:options], @api_client, {})
3829
- if params['zoneId']
3830
- if params['zoneId'] == '' || params['zoneId'] == 'null' || params['zoneId'].to_s == '0'
3831
- params['zoneId'] = 0
3832
- else
3833
- params['zoneId'] = params['zoneId'].to_i
3820
+ params.deep_merge! Morpheus::Cli::OptionTypes.prompt(update_instance_scaling_option_types, options[:options], @api_client, {})
3821
+ source_threshold_id = params.delete('sourceThresholdId')
3822
+ customize_threshold_prompt = true
3823
+ params ||= {}
3824
+ if source_threshold_id.to_s != '' && source_threshold_id.to_s != 'custom'
3825
+ params['sourceThresholdId']= source_threshold_id.to_i
3826
+ customize_threshold_prompt = false
3827
+ end
3828
+ # always parse the threshold options but customize_threshold means prompt also
3829
+ my_option_types = instance_threshold_option_types
3830
+ if customize_threshold_prompt
3831
+ # preserve all current values by setting the prompt options defaultValue attribute
3832
+ my_option_types.each do |opt|
3833
+ field_key = opt['fieldName']
3834
+ if instance_threshold[field_key] != nil
3835
+ opt['defaultValue'] = instance_threshold[field_key]
3836
+ end
3834
3837
  end
3835
- end
3836
-
3837
- option_types_group = my_option_types.select {|opt| ['minCount', 'maxCount'].include?(opt['fieldName']) }
3838
- params.merge! Morpheus::Cli::OptionTypes.prompt(option_types_group, options[:options], @api_client, {})
3839
-
3840
- option_types_group = my_option_types.select {|opt| ['memoryEnabled'].include?(opt['fieldName']) }
3841
- params.merge! Morpheus::Cli::OptionTypes.prompt(option_types_group, options[:options], @api_client, {})
3842
- if params['memoryEnabled'] == 'on' || params['memoryEnabled'] == true
3843
- option_types_group = my_option_types.select {|opt| ['minMemory', 'maxMemory'].include?(opt['fieldName']) }
3844
- params.merge! Morpheus::Cli::OptionTypes.prompt(option_types_group, options[:options], @api_client, {})
3838
+ params.deep_merge! Morpheus::Cli::OptionTypes.prompt(my_option_types, options[:options], @api_client, {})
3845
3839
  else
3846
- params['minMemory'] = nil
3847
- params['maxMemory'] = nil
3848
- end
3849
-
3850
- option_types_group = my_option_types.select {|opt| ['diskEnabled'].include?(opt['fieldName']) }
3851
- params.merge! Morpheus::Cli::OptionTypes.prompt(option_types_group, options[:options], @api_client, {})
3852
- if params['diskEnabled'] == 'on' || params['diskEnabled'] == true
3853
- option_types_group = my_option_types.select {|opt| ['minDisk', 'maxDisk'].include?(opt['fieldName']) }
3854
- params.merge! Morpheus::Cli::OptionTypes.prompt(option_types_group, options[:options], @api_client, {})
3855
- else
3856
- params['minDisk'] = nil
3857
- params['maxDisk'] = nil
3840
+ # preserve current values by setting the prompt options defaultValue attribute
3841
+ # only prompt for autoUp and autoDown
3842
+ my_option_types.each do |opt|
3843
+ field_key = opt['fieldName']
3844
+ if ['autoUp','autoDown'].include?(field_key)
3845
+ if instance_threshold[field_key] != nil
3846
+ opt['defaultValue'] = instance_threshold[field_key]
3847
+ end
3848
+ opt['noPrompt'] = false
3849
+ else
3850
+ opt['noPrompt'] = true
3851
+ end
3852
+ end
3853
+ params.deep_merge! Morpheus::Cli::OptionTypes.prompt(my_option_types, options[:options], @api_client, {})
3858
3854
  end
3855
+ params.booleanize! # convert checkbox "on" and "off" to true and false
3856
+ payload[object_key].deep_merge!(params)
3857
+ end
3858
+ # unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to update the scaling settings for instance '#{instance['name']}'?", options)
3859
+ # return 9, "aborted command"
3860
+ # end
3861
+ @instances_interface.setopts(options)
3862
+ if options[:dry_run]
3863
+ print_dry_run @instances_interface.dry.update_threshold(instance['id'], payload)
3864
+ return
3865
+ end
3866
+ json_response = @instances_interface.update_threshold(instance['id'], payload)
3867
+ render_response(json_response, options) do
3868
+ print_green_success "Updated scaling settings for instance #{instance['name']}"
3869
+ # return _get_inventory(integration, integration_inventory["id"], {}, options)
3870
+ end
3871
+ return 0, nil
3872
+ end
3859
3873
 
3860
- option_types_group = my_option_types.select {|opt| ['cpuEnabled'].include?(opt['fieldName']) }
3861
- params.merge! Morpheus::Cli::OptionTypes.prompt(option_types_group, options[:options], @api_client, {})
3862
- if params['cpuEnabled'] == 'on' || params['cpuEnabled'] == true
3863
- option_types_group = my_option_types.select {|opt| ['minCpu', 'maxCpu'].include?(opt['fieldName']) }
3864
- params.merge! Morpheus::Cli::OptionTypes.prompt(option_types_group, options[:options], @api_client, {})
3874
+ def list_schedules(args)
3875
+ params = {}
3876
+ options = {}
3877
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
3878
+ opts.banner = subcommand_usage("[instance]")
3879
+ build_standard_get_options(opts, options) # build_standard_list_options(opts, options) # phrase,max,etc is not supported
3880
+ opts.footer = <<-EOT
3881
+ List instance scaling threshold schedules.
3882
+ [instance] is required. This is the name or id of an instance
3883
+ EOT
3884
+ end
3885
+ optparse.parse!(args)
3886
+ verify_args!(args:args, optparse:optparse, count:1)
3887
+ connect(options)
3888
+ parse_get_options!(args, options, params) # parse_list_options!(args, options, params) # phrase,max,etc is not supported
3889
+ instance = find_instance_by_name_or_id(args[0])
3890
+ return 1 if instance.nil?
3891
+ @instances_interface.setopts(options)
3892
+ if options[:dry_run]
3893
+ print_dry_run @instances_interface.dry.list_schedules(instance['id'], params)
3894
+ return 0, nil
3895
+ end
3896
+ json_response = @instances_interface.list_schedules(instance['id'], params)
3897
+ list_key = 'instanceSchedules'
3898
+ render_response(json_response, options, list_key) do
3899
+ records = json_response[list_key]
3900
+ title = "Morpheus Instance Schedules"
3901
+ subtitles = []
3902
+ subtitles += parse_list_subtitles(options)
3903
+ print_h1 title, subtitles, options
3904
+ if records.nil? || records.empty?
3905
+ print cyan,"No schedules found.",reset,"\n"
3865
3906
  else
3866
- params['minCpu'] = nil
3867
- params['maxCpu'] = nil
3907
+ print as_pretty_table(records, instance_schedule_list_column_definitions(options).upcase_keys!, options)
3908
+ print_results_pagination(json_response) if json_response['meta']
3868
3909
  end
3910
+ print reset,"\n"
3911
+ end
3912
+ return 0, nil
3869
3913
 
3870
- # argh, convert on/off to true/false
3871
- # this needs a global solution...
3872
- params.each do |k,v|
3873
- if v == 'on' || v == 'true' || v == 'yes'
3874
- params[k] = true
3875
- elsif v == 'off' || v == 'false' || v == 'no'
3876
- params[k] = false
3877
- end
3878
- end
3914
+ end
3879
3915
 
3880
- payload = {
3881
- 'instanceThreshold' => {}
3882
- }
3883
- payload['instanceThreshold'].merge!(params)
3916
+ def get_schedule(args)
3917
+ params = {}
3918
+ options = {}
3919
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
3920
+ opts.banner = subcommand_usage("[instance] [schedule]")
3921
+ # build_standard_list_options(opts, options)
3922
+ build_standard_get_options(opts, options) # phrase,max,etc is not supported
3923
+ opts.footer = <<-EOT
3924
+ Get details about an instance scaling threshold schedule.
3925
+ [instance] is required. This is the name or id of an instance
3926
+ [schedule] is required. This is id of an instance schedule
3927
+ EOT
3928
+ end
3929
+ optparse.parse!(args)
3930
+ verify_args!(args:args, optparse:optparse, count:2)
3931
+ connect(options)
3932
+ parse_get_options!(args, options, params)
3933
+ instance = find_instance_by_name_or_id(args[0])
3934
+ return 1 if instance.nil?
3935
+ @instances_interface.setopts(options)
3936
+ if options[:dry_run]
3937
+ print_dry_run @instances_interface.dry.list(instance['id'], args[1], params)
3938
+ return 0, nil
3939
+ end
3940
+ json_response = @instances_interface.get_schedule(instance['id'], args[1], params)
3941
+ object_key = 'instanceSchedule'
3942
+ render_response(json_response, options, object_key) do
3943
+ record = json_response[object_key]
3944
+ title = "Instance Schedule Details"
3945
+ print_h1 title, options
3946
+ columns = instance_schedule_column_definitions(options)
3947
+ print print_description_list(columns, record, options)
3948
+ print reset,"\n"
3949
+ end
3950
+ return 0, nil
3951
+ end
3884
3952
 
3885
- # unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to update the scaling settings for instance '#{instance['name']}'?", options)
3886
- # return 9, "aborted command"
3953
+ def add_schedule(args)
3954
+ options = {}
3955
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
3956
+ opts.banner = subcommand_usage("[instance]")
3957
+ # opts.on( '--threshold VALUE', String, "Threshold template to apply scaling settings with. Default is no template (custom)." ) do |val|
3958
+ # options[:threshold] = val
3887
3959
  # end
3888
- @instances_interface.setopts(options)
3889
- if options[:dry_run]
3890
- print_dry_run @instances_interface.dry.update_threshold(instance['id'], payload)
3891
- return
3892
- end
3893
- json_response = @instances_interface.update_threshold(instance['id'], payload)
3894
- if options[:json]
3895
- puts as_json(json_response, options)
3960
+ build_option_type_options(opts, options, add_instance_schedule_option_types)
3961
+ build_option_type_options(opts, options, instance_threshold_option_types)
3962
+ build_standard_update_options(opts, options)
3963
+ opts.footer = <<-EOT
3964
+ Update an existing instance scaling threshold schedule
3965
+ [instance] is required. This is the name or id of an instance
3966
+ EOT
3967
+ end
3968
+ optparse.parse!(args)
3969
+ verify_args!(args:args, optparse:optparse, count:1)
3970
+ connect(options)
3971
+ instance = find_instance_by_name_or_id(args[0])
3972
+ return 1 if instance.nil?
3973
+ # construct payload
3974
+ object_key = 'instanceSchedule'
3975
+ payload = parse_payload(options, object_key)
3976
+ if !payload
3977
+ # payload = {object_key => {}}
3978
+ # support -O option but avoid duplicate threshold settings... so -O maxCpu, goes under threshold only
3979
+ # could just use options -O threshold.maxCpu instead, which is what the api wants...
3980
+ payload = {object_key => parse_passed_options(options, exclude: ['sourceThresholdId'] + instance_threshold_option_types.collect {|i|i['fieldName']})}
3981
+ params = {}
3982
+ params.deep_merge! Morpheus::Cli::OptionTypes.prompt(add_instance_schedule_option_types, options[:options], @api_client, {})
3983
+ source_threshold_id = params.delete('sourceThresholdId')
3984
+ customize_threshold_prompt = true
3985
+ params['threshold'] ||= {}
3986
+ if source_threshold_id.to_s != '' && source_threshold_id.to_s != 'custom'
3987
+ #params['threshold']['id']= source_threshold_id
3988
+ params['threshold']['sourceThresholdId']= source_threshold_id.to_i
3989
+ customize_threshold_prompt = false
3990
+ end
3991
+ # always parse the threshold options but customize_threshold means prompt also
3992
+ if customize_threshold_prompt
3993
+ params['threshold'].deep_merge! Morpheus::Cli::OptionTypes.prompt(instance_threshold_option_types, options[:options], @api_client, {})
3896
3994
  else
3897
- print_green_success "Updated scaling settings for instance #{instance['name']}"
3995
+ params['threshold'].deep_merge! Morpheus::Cli::OptionTypes.no_prompt(instance_threshold_option_types, options[:options], @api_client, {})
3898
3996
  end
3899
- return 0
3900
- rescue RestClient::Exception => e
3901
- print_rest_exception(e, options)
3902
- exit 1
3997
+ params.booleanize! # convert checkbox "on" and "off" to true and false
3998
+ payload[object_key].deep_merge!(params)
3999
+ # unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to update the scaling settings for instance '#{instance['name']}' with the above scaling schedule?", options)
4000
+ # return 9, "aborted command"
4001
+ # end
3903
4002
  end
4003
+ @instances_interface.setopts(options)
4004
+ if options[:dry_run]
4005
+ print_dry_run @instances_interface.dry.create_schedule(instance['id'], payload)
4006
+ return 0, nil
4007
+ end
4008
+ json_response = @instances_interface.create_schedule(instance['id'], payload)
4009
+ render_response(json_response, options) do
4010
+ print_green_success "Added scaling schedule for instance #{instance['name']}"
4011
+ #_scaling(instance['id'], options)
4012
+ end
4013
+ return 0, nil
4014
+ end
4015
+
4016
+ def update_schedule(args)
4017
+ options = {}
4018
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
4019
+ opts.banner = subcommand_usage("[instance] [schedule]")
4020
+ build_option_type_options(opts, options, update_instance_schedule_option_types)
4021
+ build_option_type_options(opts, options, instance_threshold_option_types)
4022
+ build_standard_update_options(opts, options)
4023
+ opts.footer = <<-EOT
4024
+ Update an existing instance scaling threshold schedule.
4025
+ [instance] is required. This is the name or id of an instance
4026
+ [schedule] is required. This is id of an instance schedule
4027
+ EOT
4028
+ end
4029
+ optparse.parse!(args)
4030
+ verify_args!(args:args, optparse:optparse, count:2)
4031
+ connect(options)
4032
+ instance = find_instance_by_name_or_id(args[0])
4033
+ return 1, "Instance not found for '#{args[0]}'" if instance.nil?
4034
+ instance_schedule = find_instance_schedule_by_id(instance['id'], args[1])
4035
+ return 1, "Instance schedule not found for '#{args[1]}'" if instance_schedule.nil?
4036
+ # construct payload
4037
+ object_key = 'instanceSchedule'
4038
+ payload = parse_payload(options, object_key)
4039
+ if !payload
4040
+ # payload = {object_key => {}}
4041
+ # support -O option but avoid duplicate threshold settings... so -O maxCpu, goes under threshold only
4042
+ # could just use options -O threshold.maxCpu instead, which is what the api wants...
4043
+ payload = {object_key => parse_passed_options(options, exclude: ['sourceThresholdId'] + instance_threshold_option_types.collect {|i|i['fieldName']})}
4044
+ params = {}
4045
+ params.deep_merge! Morpheus::Cli::OptionTypes.no_prompt(update_instance_schedule_option_types, options[:options], @api_client, {})
4046
+ source_threshold_id = params.delete('sourceThresholdId')
4047
+ customize_threshold_prompt = true
4048
+ params['threshold'] ||= {}
4049
+ if source_threshold_id.to_s != '' && source_threshold_id.to_s != 'custom'
4050
+ #params['threshold']['id']= source_threshold_id
4051
+ params['threshold']['sourceThresholdId']= source_threshold_id.to_i
4052
+ customize_threshold_prompt = false
4053
+ end
4054
+ params['threshold'].deep_merge! Morpheus::Cli::OptionTypes.no_prompt(instance_threshold_option_types, options[:options], @api_client, {})
4055
+ params.booleanize! # convert checkbox "on" and "off" to true and false
4056
+ payload[object_key].deep_merge!(params)
4057
+ if (payload[object_key].keys - ['threshold']).empty? && payload[object_key]['threshold'].empty?
4058
+ raise_command_error "Specify at least one option to update.\n#{optparse}"
4059
+ end
4060
+ # unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to update the scaling settings for instance '#{instance['name']}' with the above scaling schedule?", options)
4061
+ # return 9, "aborted command"
4062
+ # end
4063
+ end
4064
+ @instances_interface.setopts(options)
4065
+ if options[:dry_run]
4066
+ print_dry_run @instances_interface.dry.update_schedule(instance['id'], instance_schedule['id'], payload)
4067
+ return 0, nil
4068
+ end
4069
+ json_response = @instances_interface.update_schedule(instance['id'], instance_schedule['id'], payload)
4070
+ render_response(json_response, options) do
4071
+ print_green_success "Updated scaling schedule for instance #{instance['name']}"
4072
+ #_scaling(instance['id'], options)
4073
+ end
4074
+ return 0, nil
4075
+ end
4076
+
4077
+ def remove_schedule(args)
4078
+ params = {}
4079
+ options = {}
4080
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
4081
+ opts.banner = subcommand_usage("[instance] [schedule]")
4082
+ build_standard_remove_options(opts, options)
4083
+ opts.footer = <<-EOT
4084
+ Delete an existing instance scaling threshold schedule
4085
+ [instance] is required. This is the name or id of an instance
4086
+ [schedule] is required. This is id of an instance schedule
4087
+ EOT
4088
+ end
4089
+ optparse.parse!(args)
4090
+ verify_args!(args:args, optparse:optparse, count:2)
4091
+ connect(options)
4092
+ params.merge!(parse_query_options(options))
4093
+ instance = find_instance_by_name_or_id(args[0])
4094
+ return 1, "Instance not found for '#{args[0]}'" if instance.nil?
4095
+ instance_schedule = find_instance_schedule_by_id(instance['id'], args[1])
4096
+ return 1, "Instance schedule not found for '#{args[1]}'" if instance_schedule.nil?
4097
+ unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the instance schedule #{instance_schedule['id']}?")
4098
+ return 9, "aborted"
4099
+ end
4100
+ @instances_interface.setopts(options)
4101
+ if options[:dry_run]
4102
+ print_dry_run @instances_interface.dry.destroy_schedule(instance['id'], instance_schedule['id'], params)
4103
+ return 0, nil
4104
+ end
4105
+ json_response = @instances_interface.destroy_schedule(instance['id'], instance_schedule['id'], params)
4106
+ render_response(json_response, options) do
4107
+ print_green_success "Removed instance schedule #{instance_schedule['id']}"
4108
+ end
4109
+ return 0, nil
3904
4110
  end
3905
4111
 
3906
4112
  def load_balancer_update(args)
@@ -3990,7 +4196,6 @@ EOT
3990
4196
  options = {}
3991
4197
  optparse = Morpheus::Cli::OptionParser.new do|opts|
3992
4198
  opts.banner = subcommand_usage("[instance]")
3993
- build_option_type_options(opts, options, instance_scaling_option_types(nil))
3994
4199
  build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
3995
4200
  opts.footer = "Remove a load balancer from an instance."
3996
4201
  end
@@ -4364,7 +4569,7 @@ EOT
4364
4569
  end
4365
4570
  opts.on('--file FILE', "File containing the script. This can be used instead of --script" ) do |filename|
4366
4571
  full_filename = File.expand_path(filename)
4367
- if File.exists?(full_filename)
4572
+ if File.exist?(full_filename)
4368
4573
  script_content = File.read(full_filename)
4369
4574
  else
4370
4575
  print_red_alert "File not found: #{full_filename}"
@@ -5104,50 +5309,25 @@ private
5104
5309
  end
5105
5310
  end
5106
5311
 
5107
- def instance_scaling_option_types(instance=nil)
5108
-
5109
- # Group
5110
- group_id = nil
5111
- if instance && instance['group']
5112
- group_id = instance['group']['id']
5113
- end
5114
-
5115
- available_clouds = group_id ? get_available_clouds(group_id) : []
5116
- zone_dropdown = [{'name' => 'Use Scale Priority', 'value' => 0}]
5117
- zone_dropdown += available_clouds.collect {|cloud| {'name' => cloud['name'], 'value' => cloud['id']} }
5118
-
5119
- list = []
5120
- list << {'fieldName' => 'autoUp', 'fieldLabel' => 'Auto Upscale', 'type' => 'checkbox', 'description' => 'Enable auto upscaling', 'required' => true, 'defaultValue' => false}
5121
- list << {'fieldName' => 'autoDown', 'fieldLabel' => 'Auto Downscale', 'type' => 'checkbox', 'description' => 'Enable auto downscaling', 'required' => true, 'defaultValue' => false}
5122
-
5123
- list << {'fieldName' => 'zoneId', 'fieldLabel' => 'Cloud', 'type' => 'select', 'selectOptions' => zone_dropdown, 'description' => "Choose a cloud to scale into.", 'placeHolder' => 'ID'}
5124
-
5125
- list << {'fieldName' => 'minCount', 'fieldLabel' => 'Min Count', 'type' => 'number', 'description' => 'Minimum number of nodes', 'placeHolder' => 'NUMBER'}
5126
- list << {'fieldName' => 'maxCount', 'fieldLabel' => 'Max Count', 'type' => 'number', 'description' => 'Maximum number of nodes', 'placeHolder' => 'NUMBER'}
5127
-
5128
-
5129
- list << {'fieldName' => 'memoryEnabled', 'fieldLabel' => 'Enable Memory Threshold', 'type' => 'checkbox', 'description' => 'Scale when memory thresholds are met.', 'required' => true, 'defaultValue' => false}
5130
- list << {'fieldName' => 'minMemory', 'fieldLabel' => 'Min Memory', 'type' => 'number', 'description' => 'Minimum memory percent (0-100)', 'placeHolder' => 'PERCENT'}
5131
- list << {'fieldName' => 'maxMemory', 'fieldLabel' => 'Max Memory', 'type' => 'number', 'description' => 'Maximum memory percent (0-100)', 'placeHolder' => 'PERCENT'}
5132
-
5133
- list << {'fieldName' => 'diskEnabled', 'fieldLabel' => 'Enable Disk Threshold', 'type' => 'checkbox', 'description' => 'Scale when disk thresholds are met.', 'required' => true, 'defaultValue' => false}
5134
- list << {'fieldName' => 'minDisk', 'fieldLabel' => 'Min Disk', 'type' => 'number', 'description' => 'Minimum storage percent (0-100)', 'placeHolder' => 'PERCENT'}
5135
- list << {'fieldName' => 'maxDisk', 'fieldLabel' => 'Max Disk', 'type' => 'number', 'description' => 'Maximum storage percent (0-100)', 'placeHolder' => 'PERCENT'}
5136
-
5137
- list << {'fieldName' => 'cpuEnabled', 'fieldLabel' => 'Enable CPU Threshold', 'type' => 'checkbox', 'description' => 'Scale when cpu thresholds are met.', 'required' => true, 'defaultValue' => false}
5138
- list << {'fieldName' => 'minCpu', 'fieldLabel' => 'Min CPU', 'type' => 'number', 'description' => 'Minimum CPU percent (0-100)', 'placeHolder' => 'PERCENT'}
5139
- list << {'fieldName' => 'maxCpu', 'fieldLabel' => 'Max CPU', 'type' => 'number', 'description' => 'Maximum CPU percent (0-100)', 'placeHolder' => 'PERCENT'}
5140
-
5141
- # list << {'fieldName' => 'iopsEnabled', 'fieldLabel' => 'Enable Iops Threshold', 'type' => 'checkbox', 'description' => 'Scale when iops thresholds are met.'}
5142
- # list << {'fieldName' => 'minIops', 'fieldLabel' => 'Min Iops', 'type' => 'number', 'description' => 'Minimum iops'}
5143
- # list << {'fieldName' => 'maxIops', 'fieldLabel' => 'Max Iops', 'type' => 'number', 'description' => 'Maximum iops'}
5144
-
5145
- # list << {'fieldName' => 'networkEnabled', 'fieldLabel' => 'Enable Iops Threshold', 'type' => 'checkbox', 'description' => 'Scale when network thresholds are met.'}
5146
- # list << {'fieldName' => 'minNetwork', 'fieldLabel' => 'Min Network', 'type' => 'number', 'description' => 'Minimum networking'}
5147
-
5148
- # list << {'fieldName' => 'comment', 'fieldLabel' => 'Comment', 'type' => 'text', 'description' => 'Comment on these scaling settings.'}
5149
-
5150
- list
5312
+ def update_instance_scaling_option_types()
5313
+ [
5314
+ {'code' => 'sourceThresholdId', 'switch' => 'threshold', 'fieldName' => 'sourceThresholdId', 'fieldLabel' => 'Threshold', 'type' => 'select', 'optionSource' => lambda {|api_client, api_params|
5315
+ [{'name' => 'Custom', 'value' => 'custom'}] + api_client.options.options_for_source('instanceThresholdTemplates')['data'] rescue []
5316
+ }, 'description' => "Threshold template to use as source for scaling threshold settings.", 'defaultValue' => 'custom', 'required' => true}, #, 'required' => true, 'defaultValue' => ''},
5317
+ # {'fieldName' => 'autoUp', 'fieldLabel' => 'Auto Upscale', 'type' => 'checkbox', 'description' => 'Enable auto upscaling'},
5318
+ # {'fieldName' => 'autoDown', 'fieldLabel' => 'Auto Downscale', 'type' => 'checkbox', 'description' => 'Enable auto downscaling'},
5319
+ # {'dependsOnCode' => 'sourceThresholdId:custom', 'fieldName' => 'minCount', 'fieldLabel' => 'Min Count', 'type' => 'number', 'description' => 'Minimum number of nodes'},
5320
+ # {'dependsOnCode' => 'sourceThresholdId:custom', 'fieldName' => 'maxCount', 'fieldLabel' => 'Max Count', 'type' => 'number', 'description' => 'Maximum number of nodes'},
5321
+ # {'dependsOnCode' => 'sourceThresholdId:custom', 'fieldName' => 'cpuEnabled', 'fieldLabel' => 'Enable CPU Threshold', 'type' => 'checkbox', 'description' => 'Scale when CPU thresholds are met.'},
5322
+ # {'dependsOnCode' => 'sourceThresholdId:custom', 'fieldName' => 'minCpu', 'fieldLabel' => 'Min CPU', 'type' => 'number', 'description' => 'Minimum CPU percent (0-100)'},
5323
+ # {'dependsOnCode' => 'sourceThresholdId:custom', 'fieldName' => 'maxCpu', 'fieldLabel' => 'Max CPU', 'type' => 'number', 'description' => 'Maximum CPU percent (0-100)'},
5324
+ # {'dependsOnCode' => 'sourceThresholdId:custom', 'fieldName' => 'memoryEnabled', 'fieldLabel' => 'Enable Memory Threshold', 'type' => 'checkbox', 'description' => 'Scale when memory thresholds are met.'},
5325
+ # {'dependsOnCode' => 'sourceThresholdId:custom', 'fieldName' => 'minMemory', 'fieldLabel' => 'Min Memory', 'type' => 'number', 'description' => 'Minimum memory percent (0-100)'},
5326
+ # {'dependsOnCode' => 'sourceThresholdId:custom', 'fieldName' => 'maxMemory', 'fieldLabel' => 'Max Memory', 'type' => 'number', 'description' => 'Maximum memory percent (0-100)'},
5327
+ # {'dependsOnCode' => 'sourceThresholdId:custom', 'fieldName' => 'diskEnabled', 'fieldLabel' => 'Enable Disk Threshold', 'type' => 'checkbox', 'description' => 'Scale when storage thresholds are met.'},
5328
+ # {'dependsOnCode' => 'sourceThresholdId:custom', 'fieldName' => 'minDisk', 'fieldLabel' => 'Min Disk', 'type' => 'number', 'description' => 'Minimum storage percent (0-100)'},
5329
+ # {'dependsOnCode' => 'sourceThresholdId:custom', 'fieldName' => 'maxDisk', 'fieldLabel' => 'Max Disk', 'type' => 'number', 'description' => 'Maximum storage percent (0-100)'},
5330
+ ]
5151
5331
  end
5152
5332
 
5153
5333
  def instance_load_balancer_option_types(instance=nil)
@@ -5162,7 +5342,7 @@ private
5162
5342
  # "Instance" => lambda {|it| "#{instance['id']} - #{instance['name']}" },
5163
5343
  "Auto Upscale" => lambda {|it| format_boolean(it['autoUp']) },
5164
5344
  "Auto Downscale" => lambda {|it| format_boolean(it['autoDown']) },
5165
- "Cloud" => lambda {|it| it['zoneId'] ? "#{it['zoneId']}" : 'Use Scale Priority' },
5345
+ #"Cloud" => lambda {|it| it['zoneId'] ? "#{it['zoneId']}" : 'Use Scale Priority' },
5166
5346
  "Min Count" => lambda {|it| it['minCount'] },
5167
5347
  "Max Count" => lambda {|it| it['maxCount'] },
5168
5348
  "Memory Enabled" => lambda {|it| format_boolean(it['memoryEnabled']) },
@@ -5183,6 +5363,96 @@ private
5183
5363
  print_description_list(description_cols, instance_threshold)
5184
5364
  end
5185
5365
 
5366
+ def instance_schedule_column_definitions(options)
5367
+ {
5368
+ "ID" => lambda {|it| it['id'] },
5369
+ "Start" => lambda {|it| it['startDisplay'] },
5370
+ "End" => lambda {|it| it['endDisplay'] },
5371
+ "Auto Upscale" => lambda {|it| format_boolean(it['threshold']['autoUp']) rescue nil },
5372
+ "Auto Downscale" => lambda {|it| format_boolean(it['threshold']['autoDown']) rescue nil },
5373
+ "Min Count" => lambda {|it| it['threshold']['minCount'] rescue nil },
5374
+ "Max Count" => lambda {|it| it['threshold']['maxCount'] rescue nil },
5375
+ "Enable CPU Threshold" => lambda {|it| format_boolean(it['threshold']['cpuEnabled']) rescue nil },
5376
+ "Min CPU" => lambda {|it| format_percent(it['threshold']['minCpu'], 9, true) rescue nil },
5377
+ "Max CPU" => lambda {|it| format_percent(it['threshold']['maxCpu'], 9, true) rescue nil },
5378
+ "Enable Memory Threshold" => lambda {|it| format_boolean(it['threshold']['memoryEnabled']) rescue nil },
5379
+ "Min Memory" => lambda {|it| format_percent(it['threshold']['minMemory'], 9, true) rescue nil },
5380
+ "Max Memory" => lambda {|it| format_percent(it['threshold']['maxMemory'], 9, true) rescue nil },
5381
+ "Enable Disk Threshold" => lambda {|it| format_boolean(it['threshold']['diskEnabled']) rescue nil },
5382
+ "Min Disk" => lambda {|it| format_percent(it['threshold']['minDisk'], 9, true) rescue nil },
5383
+ "Max Disk" => lambda {|it| format_percent(it['threshold']['maxDisk'], 9, true) rescue nil },
5384
+ }
5385
+ end
5386
+
5387
+ def instance_schedule_list_column_definitions(options)
5388
+ instance_schedule_column_definitions(options)
5389
+ end
5390
+
5391
+ def find_instance_schedule_by_id(instance_id, id)
5392
+ begin
5393
+ json_response = @instances_interface.get_schedule(instance_id, id)
5394
+ return json_response['instanceSchedule']
5395
+ rescue RestClient::Exception => e
5396
+ if e.response && e.response.code == 404
5397
+ print_red_alert "Instance Schedule not found by id #{id}"
5398
+ exit 1
5399
+ else
5400
+ raise e
5401
+ end
5402
+ end
5403
+ end
5404
+
5405
+ def day_of_week_dropdown()
5406
+ [
5407
+ {'name' => 'Sunday', 'value' => 1},
5408
+ {'name' => 'Monday', 'value' => 2},
5409
+ {'name' => 'Tuesday', 'value' => 3},
5410
+ {'name' => 'Wednesday', 'value' => 4},
5411
+ {'name' => 'Thursday', 'value' => 5},
5412
+ {'name' => 'Friday', 'value' => 6},
5413
+ {'name' => 'Saturday', 'value' => 7}
5414
+ ]
5415
+ end
5416
+
5417
+ def add_instance_schedule_option_types()
5418
+ [
5419
+ {'code' => 'scheduleType', 'fieldName' => 'scheduleType', 'fieldLabel' => 'Schedule Type', 'type' => 'select', 'selectOptions' => [{'name'=>'Day Of Week', 'value'=>'dayOfWeek'},{'name'=>'Exact', 'value'=>'exact'}], 'description' => "Schedule type can be recurring day of the week str or exact start and end timestamp", 'required' => true, 'defaultValue' => 'dayOfWeek'},
5420
+ {'dependsOnCode' => 'scheduleType:dayOfWeek', 'fieldName' => 'startDayOfWeek', 'fieldLabel' => 'Start Day Of Week', 'type' => 'select', 'selectOptions' => day_of_week_dropdown, 'description' => "Start day of the week Sunday-Saturday (1-7)", 'defaultValue' => "Sunday", 'required' => true},
5421
+ {'dependsOnCode' => 'scheduleType:dayOfWeek', 'fieldName' => 'startTime', 'fieldLabel' => 'Start Time (HH:MM)', 'type' => 'text', 'description' => "Start time in HH:MM 24-hour format", 'placeHolder' => 'HH:MM', 'defaultValue' => "01:00", 'required' => true},
5422
+ {'dependsOnCode' => 'scheduleType:dayOfWeek', 'fieldName' => 'endDayOfWeek', 'fieldLabel' => 'End Day Of Week', 'type' => 'select', 'selectOptions' => day_of_week_dropdown, 'description' => "End day of the week Sunday-Saturday (1-7)", 'defaultValue' => "Sunday", 'required' => true},
5423
+ {'dependsOnCode' => 'scheduleType:dayOfWeek', 'fieldName' => 'endTime', 'fieldLabel' => 'End Time (HH:MM)', 'type' => 'text', 'description' => "End time in HH:MM 24-hour format", 'placeHolder' => 'HH:MM', 'defaultValue' => "01:00", 'required' => true},
5424
+ {'dependsOnCode' => 'scheduleType:exact', 'fieldName' => 'startDate', 'fieldLabel' => 'Start Date', 'type' => 'text', 'description' => "Exact start date timestamp in standard iso8601 format", 'placeHolder' => 'YYYY-MM-DD', 'required' => true},
5425
+ {'dependsOnCode' => 'scheduleType:exact', 'fieldName' => 'endDate', 'fieldLabel' => 'End Date', 'type' => 'text', 'description' => "Exact end date timestamp in standard iso8601 format", 'placeHolder' => 'YYYY-MM-DD', 'required' => true},
5426
+ {'switch' => 'threshold', 'fieldName' => 'sourceThresholdId', 'fieldLabel' => 'Threshold', 'type' => 'select', 'optionSource' => lambda {|api_client, api_params|
5427
+ [{'name' => 'Custom', 'value' => 'custom'}] + api_client.options.options_for_source('instanceThresholdTemplates')['data'] # rescue []
5428
+ }, 'description' => "Threshold template to use as source for scaling threshold settings.", 'defaultValue' => 'custom', 'required' => true}, #, 'required' => true, 'defaultValue' => ''},
5429
+ ]
5430
+ end
5431
+
5432
+ def update_instance_schedule_option_types()
5433
+ option_types = add_instance_schedule_option_types.collect {|it| it.delete('required'); it.delete('defaultValue'); it.delete('dependsOnCode'); it }
5434
+ #option_types.reject! {|it| it['fieldName'] == 'sourceThresholdId' }
5435
+ option_types
5436
+ end
5437
+
5438
+ def instance_threshold_option_types()
5439
+ [
5440
+ {'fieldName' => 'autoUp', 'fieldLabel' => 'Auto Upscale', 'type' => 'checkbox', 'description' => 'Enable auto upscaling'},
5441
+ {'fieldName' => 'autoDown', 'fieldLabel' => 'Auto Downscale', 'type' => 'checkbox', 'description' => 'Enable auto downscaling'},
5442
+ {'fieldName' => 'minCount', 'fieldLabel' => 'Min Count', 'type' => 'number', 'description' => 'Minimum number of nodes'},
5443
+ {'fieldName' => 'maxCount', 'fieldLabel' => 'Max Count', 'type' => 'number', 'description' => 'Maximum number of nodes'},
5444
+ {'fieldName' => 'cpuEnabled', 'fieldLabel' => 'Enable CPU Threshold', 'type' => 'checkbox', 'description' => 'Scale when CPU thresholds are met.'},
5445
+ {'fieldName' => 'minCpu', 'fieldLabel' => 'Min CPU', 'type' => 'number', 'description' => 'Minimum CPU percent (0-100)'},
5446
+ {'fieldName' => 'maxCpu', 'fieldLabel' => 'Max CPU', 'type' => 'number', 'description' => 'Maximum CPU percent (0-100)'},
5447
+ {'fieldName' => 'memoryEnabled', 'fieldLabel' => 'Enable Memory Threshold', 'type' => 'checkbox', 'description' => 'Scale when memory thresholds are met.'},
5448
+ {'fieldName' => 'minMemory', 'fieldLabel' => 'Min Memory', 'type' => 'number', 'description' => 'Minimum memory percent (0-100)'},
5449
+ {'fieldName' => 'maxMemory', 'fieldLabel' => 'Max Memory', 'type' => 'number', 'description' => 'Maximum memory percent (0-100)'},
5450
+ {'fieldName' => 'diskEnabled', 'fieldLabel' => 'Enable Disk Threshold', 'type' => 'checkbox', 'description' => 'Scale when storage thresholds are met.'},
5451
+ {'fieldName' => 'minDisk', 'fieldLabel' => 'Min Disk', 'type' => 'number', 'description' => 'Minimum storage percent (0-100)'},
5452
+ {'fieldName' => 'maxDisk', 'fieldLabel' => 'Max Disk', 'type' => 'number', 'description' => 'Maximum storage percent (0-100)'},
5453
+ ]
5454
+ end
5455
+
5186
5456
  def print_process_details(process)
5187
5457
  description_cols = {
5188
5458
  "Process ID" => lambda {|it| it['id'] },
@@ -5285,4 +5555,5 @@ private
5285
5555
  return false
5286
5556
  end
5287
5557
  end
5558
+
5288
5559
  end