morpheus-cli 5.3.0.1 → 5.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/README.md +1 -3
  4. data/lib/morpheus/api/account_groups_interface.rb +0 -6
  5. data/lib/morpheus/api/accounts_interface.rb +1 -7
  6. data/lib/morpheus/api/api_client.rb +155 -119
  7. data/lib/morpheus/api/appliance_settings_interface.rb +6 -9
  8. data/lib/morpheus/api/approvals_interface.rb +5 -8
  9. data/lib/morpheus/api/apps_interface.rb +0 -7
  10. data/lib/morpheus/api/archive_buckets_interface.rb +9 -16
  11. data/lib/morpheus/api/archive_files_interface.rb +0 -6
  12. data/lib/morpheus/api/auth_interface.rb +4 -4
  13. data/lib/morpheus/api/backup_settings_interface.rb +5 -8
  14. data/lib/morpheus/api/blueprints_interface.rb +1 -7
  15. data/lib/morpheus/api/budgets_interface.rb +0 -6
  16. data/lib/morpheus/api/certificate_types_interface.rb +14 -0
  17. data/lib/morpheus/api/certificates_interface.rb +9 -0
  18. data/lib/morpheus/api/cloud_datastores_interface.rb +0 -6
  19. data/lib/morpheus/api/cloud_folders_interface.rb +1 -7
  20. data/lib/morpheus/api/cloud_policies_interface.rb +0 -6
  21. data/lib/morpheus/api/cloud_resource_pools_interface.rb +0 -6
  22. data/lib/morpheus/api/clouds_interface.rb +0 -6
  23. data/lib/morpheus/api/clusters_interface.rb +39 -42
  24. data/lib/morpheus/api/containers_interface.rb +0 -6
  25. data/lib/morpheus/api/custom_instance_types_interface.rb +0 -6
  26. data/lib/morpheus/api/cypher_interface.rb +0 -6
  27. data/lib/morpheus/api/datastores_interface.rb +4 -7
  28. data/lib/morpheus/api/deploy_interface.rb +1 -6
  29. data/lib/morpheus/api/environments_interface.rb +0 -6
  30. data/lib/morpheus/api/execute_schedules_interface.rb +0 -6
  31. data/lib/morpheus/api/execution_request_interface.rb +0 -6
  32. data/lib/morpheus/api/file_copy_request_interface.rb +2 -9
  33. data/lib/morpheus/api/group_policies_interface.rb +0 -6
  34. data/lib/morpheus/api/groups_interface.rb +0 -7
  35. data/lib/morpheus/api/guidance_interface.rb +9 -12
  36. data/lib/morpheus/api/health_interface.rb +0 -6
  37. data/lib/morpheus/api/image_builder_boot_scripts_interface.rb +0 -6
  38. data/lib/morpheus/api/image_builder_image_builds_interface.rb +0 -6
  39. data/lib/morpheus/api/image_builder_interface.rb +3 -9
  40. data/lib/morpheus/api/image_builder_preseed_scripts_interface.rb +0 -6
  41. data/lib/morpheus/api/instance_types_interface.rb +0 -7
  42. data/lib/morpheus/api/instances_interface.rb +8 -19
  43. data/lib/morpheus/api/integration_types_interface.rb +14 -0
  44. data/lib/morpheus/api/integrations_interface.rb +36 -21
  45. data/lib/morpheus/api/invoice_line_items_interface.rb +4 -9
  46. data/lib/morpheus/api/jobs_interface.rb +11 -14
  47. data/lib/morpheus/api/key_pairs_interface.rb +0 -6
  48. data/lib/morpheus/api/library_cluster_layouts_interface.rb +0 -6
  49. data/lib/morpheus/api/library_container_scripts_interface.rb +0 -6
  50. data/lib/morpheus/api/library_container_templates_interface.rb +0 -6
  51. data/lib/morpheus/api/library_container_types_interface.rb +0 -6
  52. data/lib/morpheus/api/library_container_upgrades_interface.rb +0 -6
  53. data/lib/morpheus/api/library_instance_types_interface.rb +0 -6
  54. data/lib/morpheus/api/library_layouts_interface.rb +0 -6
  55. data/lib/morpheus/api/library_spec_template_types_interface.rb +0 -6
  56. data/lib/morpheus/api/library_spec_templates_interface.rb +0 -6
  57. data/lib/morpheus/api/license_interface.rb +0 -6
  58. data/lib/morpheus/api/load_balancers_interface.rb +0 -6
  59. data/lib/morpheus/api/log_settings_interface.rb +9 -12
  60. data/lib/morpheus/api/logs_interface.rb +0 -6
  61. data/lib/morpheus/api/monitoring_alerts_interface.rb +0 -6
  62. data/lib/morpheus/api/monitoring_apps_interface.rb +0 -6
  63. data/lib/morpheus/api/monitoring_checks_interface.rb +0 -6
  64. data/lib/morpheus/api/monitoring_contacts_interface.rb +0 -6
  65. data/lib/morpheus/api/monitoring_groups_interface.rb +0 -6
  66. data/lib/morpheus/api/monitoring_incidents_interface.rb +0 -6
  67. data/lib/morpheus/api/monitoring_interface.rb +6 -12
  68. data/lib/morpheus/api/network_domain_records_interface.rb +0 -6
  69. data/lib/morpheus/api/network_domains_interface.rb +0 -6
  70. data/lib/morpheus/api/network_groups_interface.rb +0 -6
  71. data/lib/morpheus/api/network_pool_ips_interface.rb +0 -6
  72. data/lib/morpheus/api/network_pool_servers_interface.rb +0 -6
  73. data/lib/morpheus/api/network_pools_interface.rb +0 -6
  74. data/lib/morpheus/api/network_proxies_interface.rb +0 -6
  75. data/lib/morpheus/api/network_routers_interface.rb +0 -6
  76. data/lib/morpheus/api/network_security_servers_interface.rb +6 -9
  77. data/lib/morpheus/api/network_services_interface.rb +14 -14
  78. data/lib/morpheus/api/network_subnets_interface.rb +0 -6
  79. data/lib/morpheus/api/network_types_interface.rb +1 -7
  80. data/lib/morpheus/api/networks_interface.rb +0 -6
  81. data/lib/morpheus/api/option_type_lists_interface.rb +18 -12
  82. data/lib/morpheus/api/option_types_interface.rb +0 -6
  83. data/lib/morpheus/api/options_interface.rb +0 -6
  84. data/lib/morpheus/api/packages_interface.rb +0 -6
  85. data/lib/morpheus/api/policies_interface.rb +1 -8
  86. data/lib/morpheus/api/power_schedules_interface.rb +0 -6
  87. data/lib/morpheus/api/price_sets_interface.rb +8 -11
  88. data/lib/morpheus/api/prices_interface.rb +12 -15
  89. data/lib/morpheus/api/processes_interface.rb +0 -6
  90. data/lib/morpheus/api/provision_types_interface.rb +0 -6
  91. data/lib/morpheus/api/provisioning_license_types_interface.rb +0 -6
  92. data/lib/morpheus/api/provisioning_licenses_interface.rb +0 -6
  93. data/lib/morpheus/api/provisioning_settings_interface.rb +6 -9
  94. data/lib/morpheus/api/read_interface.rb +23 -0
  95. data/lib/morpheus/api/reports_interface.rb +0 -6
  96. data/lib/morpheus/api/rest_interface.rb +12 -10
  97. data/lib/morpheus/api/roles_interface.rb +7 -6
  98. data/lib/morpheus/api/security_group_rules_interface.rb +0 -7
  99. data/lib/morpheus/api/security_groups_interface.rb +0 -6
  100. data/lib/morpheus/api/server_types_interface.rb +0 -6
  101. data/lib/morpheus/api/servers_interface.rb +7 -6
  102. data/lib/morpheus/api/service_plans_interface.rb +11 -14
  103. data/lib/morpheus/api/storage_providers_interface.rb +9 -16
  104. data/lib/morpheus/api/subnet_types_interface.rb +1 -7
  105. data/lib/morpheus/api/subnets_interface.rb +0 -6
  106. data/lib/morpheus/api/task_sets_interface.rb +0 -6
  107. data/lib/morpheus/api/tasks_interface.rb +0 -6
  108. data/lib/morpheus/api/user_groups_interface.rb +0 -6
  109. data/lib/morpheus/api/user_settings_interface.rb +38 -18
  110. data/lib/morpheus/api/user_sources_interface.rb +0 -6
  111. data/lib/morpheus/api/users_interface.rb +0 -6
  112. data/lib/morpheus/api/vdi_allocations_interface.rb +9 -0
  113. data/lib/morpheus/api/vdi_apps_interface.rb +9 -0
  114. data/lib/morpheus/api/vdi_gateways_interface.rb +9 -0
  115. data/lib/morpheus/api/vdi_interface.rb +28 -0
  116. data/lib/morpheus/api/vdi_pools_interface.rb +19 -0
  117. data/lib/morpheus/api/virtual_images_interface.rb +0 -6
  118. data/lib/morpheus/api/whitelabel_settings_interface.rb +8 -11
  119. data/lib/morpheus/api/wiki_interface.rb +0 -6
  120. data/lib/morpheus/cli.rb +9 -2
  121. data/lib/morpheus/cli/access_token_command.rb +1 -1
  122. data/lib/morpheus/cli/account_groups_command.rb +4 -4
  123. data/lib/morpheus/cli/apps.rb +68 -84
  124. data/lib/morpheus/cli/archives_command.rb +5 -5
  125. data/lib/morpheus/cli/blueprints_command.rb +5 -5
  126. data/lib/morpheus/cli/boot_scripts_command.rb +1 -1
  127. data/lib/morpheus/cli/catalog_item_types_command.rb +13 -13
  128. data/lib/morpheus/cli/certificates_command.rb +575 -0
  129. data/lib/morpheus/cli/change_password_command.rb +4 -4
  130. data/lib/morpheus/cli/cli_command.rb +63 -7
  131. data/lib/morpheus/cli/clouds.rb +3 -2
  132. data/lib/morpheus/cli/clusters.rb +3 -3
  133. data/lib/morpheus/cli/commands/standard/man_command.rb +4 -5
  134. data/lib/morpheus/cli/credentials.rb +4 -11
  135. data/lib/morpheus/cli/environments_command.rb +1 -1
  136. data/lib/morpheus/cli/execute_schedules_command.rb +3 -3
  137. data/lib/morpheus/cli/hosts.rb +253 -232
  138. data/lib/morpheus/cli/image_builder_command.rb +6 -6
  139. data/lib/morpheus/cli/instance_types.rb +1 -1
  140. data/lib/morpheus/cli/instances.rb +196 -186
  141. data/lib/morpheus/cli/integrations_command.rb +1155 -42
  142. data/lib/morpheus/cli/invoices_command.rb +75 -67
  143. data/lib/morpheus/cli/key_pairs.rb +2 -2
  144. data/lib/morpheus/cli/library_cluster_layouts_command.rb +2 -3
  145. data/lib/morpheus/cli/library_container_scripts_command.rb +4 -5
  146. data/lib/morpheus/cli/library_container_templates_command.rb +5 -1
  147. data/lib/morpheus/cli/library_container_types_command.rb +8 -9
  148. data/lib/morpheus/cli/library_instance_types_command.rb +6 -7
  149. data/lib/morpheus/cli/library_layouts_command.rb +9 -5
  150. data/lib/morpheus/cli/library_option_lists_command.rb +72 -20
  151. data/lib/morpheus/cli/library_option_types_command.rb +8 -4
  152. data/lib/morpheus/cli/library_spec_templates_command.rb +3 -4
  153. data/lib/morpheus/cli/library_upgrades_command.rb +6 -6
  154. data/lib/morpheus/cli/license.rb +2 -2
  155. data/lib/morpheus/cli/load_balancers.rb +1 -1
  156. data/lib/morpheus/cli/login.rb +10 -1
  157. data/lib/morpheus/cli/mixins/option_source_helper.rb +15 -16
  158. data/lib/morpheus/cli/mixins/print_helper.rb +33 -18
  159. data/lib/morpheus/cli/mixins/provisioning_helper.rb +4 -4
  160. data/lib/morpheus/cli/mixins/vdi_helper.rb +246 -0
  161. data/lib/morpheus/cli/network_domains_command.rb +2 -2
  162. data/lib/morpheus/cli/network_routers_command.rb +22 -9
  163. data/lib/morpheus/cli/networks_command.rb +2 -2
  164. data/lib/morpheus/cli/option_types.rb +39 -34
  165. data/lib/morpheus/cli/policies_command.rb +0 -1
  166. data/lib/morpheus/cli/power_schedules_command.rb +3 -3
  167. data/lib/morpheus/cli/preseed_scripts_command.rb +1 -1
  168. data/lib/morpheus/cli/remote.rb +2 -2
  169. data/lib/morpheus/cli/reports_command.rb +5 -2
  170. data/lib/morpheus/cli/roles.rb +224 -64
  171. data/lib/morpheus/cli/security_group_rules.rb +1 -1
  172. data/lib/morpheus/cli/setup.rb +0 -1
  173. data/lib/morpheus/cli/subnets_command.rb +11 -2
  174. data/lib/morpheus/cli/tenants_command.rb +3 -3
  175. data/lib/morpheus/cli/user_groups_command.rb +3 -3
  176. data/lib/morpheus/cli/user_settings_command.rb +268 -57
  177. data/lib/morpheus/cli/user_sources_command.rb +3 -3
  178. data/lib/morpheus/cli/users.rb +3 -3
  179. data/lib/morpheus/cli/vdi_allocations_command.rb +159 -0
  180. data/lib/morpheus/cli/vdi_apps_command.rb +317 -0
  181. data/lib/morpheus/cli/vdi_command.rb +359 -0
  182. data/lib/morpheus/cli/vdi_gateways_command.rb +290 -0
  183. data/lib/morpheus/cli/vdi_pools_command.rb +571 -0
  184. data/lib/morpheus/cli/version.rb +1 -1
  185. data/lib/morpheus/cli/virtual_images.rb +1 -1
  186. data/lib/morpheus/cli/whoami.rb +0 -15
  187. data/lib/morpheus/cli/wiki_command.rb +1 -1
  188. data/lib/morpheus/rest_client.rb +30 -0
  189. data/lib/morpheus/terminal.rb +15 -7
  190. metadata +18 -2
@@ -17,10 +17,10 @@ class Morpheus::Cli::LibraryOptionTypesCommand
17
17
 
18
18
  def connect(opts)
19
19
  @api_client = establish_remote_appliance_connection(opts)
20
- @library_instance_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).library_instance_types
21
- @provision_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).provision_types
22
- @option_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).option_types
23
- @option_type_lists_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).option_type_lists
20
+ @library_instance_types_interface = @api_client.library_instance_types
21
+ @provision_types_interface = @api_client.provision_types
22
+ @option_types_interface = @api_client.option_types
23
+ @option_type_lists_interface = @api_client.option_type_lists
24
24
  end
25
25
 
26
26
  def handle(args)
@@ -35,6 +35,10 @@ class Morpheus::Cli::LibraryOptionTypesCommand
35
35
  opts.footer = "List option types."
36
36
  end
37
37
  optparse.parse!(args)
38
+ # verify_args!(args:args, optparse:optparse, count:0)
39
+ if args.count > 0
40
+ options[:phrase] = args.join(" ")
41
+ end
38
42
  connect(options)
39
43
  begin
40
44
  params = {}
@@ -26,12 +26,11 @@ class Morpheus::Cli::LibrarySpecTemplatesCommand
26
26
  opts.footer = "List spec templates."
27
27
  end
28
28
  optparse.parse!(args)
29
- connect(options)
29
+ # verify_args!(args:args, optparse:optparse, count:0)
30
30
  if args.count > 0
31
- print_error Morpheus::Terminal.angry_prompt
32
- puts_error "wrong number of arguments, expected 0 and got (#{args.count}) #{args.inspect}\n#{optparse}"
33
- return 1
31
+ options[:phrase] = args.join(" ")
34
32
  end
33
+ connect(options)
35
34
  begin
36
35
  # construct payload
37
36
  params.merge!(parse_list_options(options))
@@ -18,12 +18,12 @@ class Morpheus::Cli::LibraryUpgradesCommand
18
18
 
19
19
  def connect(opts)
20
20
  @api_client = establish_remote_appliance_connection(opts)
21
- @library_container_upgrades_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).library_container_upgrades
22
- @library_layouts_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).library_layouts
23
- @library_instance_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).library_instance_types
24
- @provision_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).provision_types
25
- @option_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).option_types
26
- @option_type_lists_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).option_type_lists
21
+ @library_container_upgrades_interface = @api_client.library_container_upgrades
22
+ @library_layouts_interface = @api_client.library_layouts
23
+ @library_instance_types_interface = @api_client.library_instance_types
24
+ @provision_types_interface = @api_client.provision_types
25
+ @option_types_interface = @api_client.option_types
26
+ @option_type_lists_interface = @api_client.option_type_lists
27
27
  end
28
28
 
29
29
  def handle(args)
@@ -20,8 +20,8 @@ class Morpheus::Cli::License
20
20
 
21
21
  def connect(opts)
22
22
  @api_client = establish_remote_appliance_connection(opts)
23
- @api_client = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url)
24
- @license_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).license
23
+ @api_client = @api_client
24
+ @license_interface = @api_client.license
25
25
  end
26
26
 
27
27
  def handle(args)
@@ -16,7 +16,7 @@ class Morpheus::Cli::LoadBalancers
16
16
 
17
17
  def connect(opts)
18
18
  @api_client = establish_remote_appliance_connection(opts)
19
- @load_balancers_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).load_balancers
19
+ @load_balancers_interface = @api_client.load_balancers
20
20
  end
21
21
 
22
22
 
@@ -36,6 +36,13 @@ class Morpheus::Cli::Login
36
36
  opts.on( '-p', '--password PASSWORD', "Password" ) do |val|
37
37
  password = val
38
38
  end
39
+ opts.on( '--password-file FILE', String, "Password File, read a file containing the password." ) do |val|
40
+ password_file = File.expand_path(val)
41
+ if !File.exists?(password_file) || !File.file?(password_file) # check readable too
42
+ raise ::OptionParser::InvalidOption.new("File not found: #{password_file}")
43
+ end
44
+ password = File.read(password_file) #.to_s.split("\n").first.strip
45
+ end
39
46
  opts.on( '-t', '--test', "Test credentials only, does not update stored credentials for the appliance." ) do
40
47
  options[:test_only] = true
41
48
  end
@@ -70,7 +77,9 @@ EOT
70
77
  # connect(options)
71
78
  @api_client = establish_remote_appliance_connection(options.merge({:no_prompt => true, :skip_verify_access_token => true, :skip_login => true}))
72
79
 
73
- if @remote_appliance[:authenticated]
80
+ if options[:test_only]
81
+ puts "Testing credentials, your current session will not be modified."
82
+ elsif @remote_appliance[:authenticated]
74
83
  puts "You will be automatically logged out of your current session as '#{@remote_appliance[:username]}'"
75
84
  end
76
85
 
@@ -178,7 +178,7 @@ module Morpheus::Cli::OptionSourceHelper
178
178
  # todo: some other common ones, accounts (tenants), etc.
179
179
  # todo: a generic set of parse and find methods like
180
180
  # like this:
181
- def parse_option_source_id_list(option_source, id_list, api_params={}, refresh=false)
181
+ def parse_option_source_id_list(option_source, id_list, api_params={}, refresh=false, allow_any_id=false)
182
182
  option_source_label = option_source.to_s # .capitalize
183
183
  option_data = load_option_source_data(option_source, api_params, refresh)
184
184
  found_ids = []
@@ -189,9 +189,8 @@ module Morpheus::Cli::OptionSourceHelper
189
189
  # never match blank nil or empty strings
190
190
  print_red_alert "#{option_source_label} cannot be not found by with a blank id!"
191
191
  return nil
192
- # elsif record_id.to_s =~ /\A\d{1,}\Z/
193
- # # always allow any ID for now..
194
- # found_ids << record_id
192
+ elsif allow_any_id && record_id.to_s =~ /\A\d{1,}\Z/
193
+ found_ids << record_id.to_i
195
194
  else
196
195
  # search with in a presedence by value, then name, then id (usually same as value)
197
196
  # exact match on value first.
@@ -228,28 +227,28 @@ module Morpheus::Cli::OptionSourceHelper
228
227
  return found_ids
229
228
  end
230
229
 
231
- def parse_cloud_id_list(id_list, api_params={}, refresh=false)
232
- parse_option_source_id_list('clouds', id_list, api_params, refresh)
230
+ def parse_cloud_id_list(id_list, api_params={}, refresh=false, allow_any_id=false)
231
+ parse_option_source_id_list('clouds', id_list, api_params, refresh, allow_any_id)
233
232
  end
234
233
 
235
- def parse_group_id_list(id_list, api_params={}, refresh=false)
236
- parse_option_source_id_list('groups', id_list, api_params, refresh)
234
+ def parse_group_id_list(id_list, api_params={}, refresh=false, allow_any_id=false)
235
+ parse_option_source_id_list('groups', id_list, api_params, refresh, allow_any_id)
237
236
  end
238
237
 
239
- def parse_user_id_list(id_list, api_params={}, refresh=false)
240
- parse_option_source_id_list('users', id_list, api_params, refresh)
238
+ def parse_user_id_list(id_list, api_params={}, refresh=false, allow_any_id=false)
239
+ parse_option_source_id_list('users', id_list, api_params, refresh, allow_any_id)
241
240
  end
242
241
 
243
- def parse_tenant_id_list(id_list, api_params={}, refresh=false)
244
- parse_option_source_id_list('allTenants', id_list, api_params, refresh)
242
+ def parse_tenant_id_list(id_list, api_params={}, refresh=false, allow_any_id=false)
243
+ parse_option_source_id_list('allTenants', id_list, api_params, refresh, allow_any_id)
245
244
  end
246
245
 
247
- # def parse_blueprints_id_list(id_list)
248
- # parse_option_source_id_list('blueprints', id_list, api_params, refresh)
246
+ # def parse_blueprints_id_list(id_list, api_params={}, refresh=false, allow_any_id=false)
247
+ # parse_option_source_id_list('blueprints', id_list, api_params, refresh, allow_any_id)
249
248
  # end
250
249
 
251
- def parse_project_id_list(id_list, api_params={}, refresh=false)
252
- parse_option_source_id_list('projects', id_list, api_params, refresh)
250
+ def parse_project_id_list(id_list, api_params={}, refresh=false, allow_any_id=false)
251
+ parse_option_source_id_list('projects', id_list, api_params, refresh, allow_any_id)
253
252
  end
254
253
 
255
254
  end
@@ -228,7 +228,8 @@ module Morpheus::Cli::PrintHelper
228
228
  out << cyan
229
229
  if payload
230
230
  out << "\n"
231
- content_type = (headers && headers['Content-Type']) ? headers['Content-Type'] : 'application/x-www-form-urlencoded'
231
+ is_multipart = (payload.is_a?(Hash) && payload[:multipart] == true)
232
+ content_type = (headers && headers['Content-Type']) ? headers['Content-Type'] : (is_multipart ? 'multipart/form-data' : 'application/x-www-form-urlencoded')
232
233
  if content_type == 'application/json'
233
234
  if payload.is_a?(String)
234
235
  begin
@@ -257,12 +258,21 @@ module Morpheus::Cli::PrintHelper
257
258
  out << payload
258
259
  end
259
260
  else
260
- if content_type == 'application/x-www-form-urlencoded'
261
+ if content_type == 'application/x-www-form-urlencoded' || content_type.to_s.include?('multipart')
261
262
  body_str = payload.to_s
262
263
  begin
264
+ payload.delete(:multipart) if payload.is_a?(Hash)
265
+ # puts "grailsifying it!"
266
+ payload = Morpheus::RestClient.grails_params(payload)
267
+ payload.each do |k,v|
268
+ if v.is_a?(File)
269
+ payload[k] = "@#{v.path}"
270
+ payload[k] = v.path
271
+ end
272
+ end
263
273
  body_str = URI.encode_www_form(payload)
264
274
  rescue => ex
265
- # raise ex
275
+ raise ex
266
276
  end
267
277
  if options[:scrub]
268
278
  out << Morpheus::Logging.scrub_message(body_str)
@@ -273,7 +283,7 @@ module Morpheus::Cli::PrintHelper
273
283
  if options[:scrub]
274
284
  out << Morpheus::Logging.scrub_message(payload)
275
285
  else
276
- out << payload
286
+ out << payload.to_s
277
287
  end
278
288
  end
279
289
  end
@@ -327,7 +337,9 @@ module Morpheus::Cli::PrintHelper
327
337
  else
328
338
  out << " -d '#{payload}'"
329
339
  end
340
+ out << "\n"
330
341
  else
342
+ is_multipart = (payload.is_a?(Hash) && payload[:multipart] == true)
331
343
  content_type = headers['Content-Type'] || 'application/x-www-form-urlencoded'
332
344
 
333
345
  if payload.is_a?(File)
@@ -337,21 +349,22 @@ module Morpheus::Cli::PrintHelper
337
349
  out << " -d @#{payload.path}"
338
350
  elsif payload.is_a?(String)
339
351
  out << " -d '#{payload}'"
340
- else
341
- if content_type == 'application/x-www-form-urlencoded'
342
- body_str = payload.to_s
343
- begin
344
- body_str = URI.encode_www_form(payload)
345
- rescue => ex
346
- # raise ex
352
+ elsif payload.respond_to?(:map)
353
+ payload.delete(:multipart) if payload.is_a?(Hash)
354
+ # puts "grailsifying it!"
355
+ payload = Morpheus::RestClient.grails_params(payload)
356
+ payload.each do |k,v|
357
+ if v.is_a?(File)
358
+ out << " -F '#{k}=@#{v.path}"
359
+ else
360
+ out << " -d '#{URI.encode_www_form({(k) => v})}'"
347
361
  end
348
- out << " -d '#{body_str}'"
349
- else
350
- out << " -d '#{payload}'"
362
+ out << "\n"
351
363
  end
364
+ #body_str = URI.encode_www_form(payload)
365
+ # out << " -d '#{body_str}'"
352
366
  end
353
367
  end
354
- out << "\n"
355
368
  else
356
369
  out << "\n"
357
370
  end
@@ -431,12 +444,13 @@ module Morpheus::Cli::PrintHelper
431
444
  out = ""
432
445
  bars = []
433
446
  percent = 0
447
+ percent_sigdig = opts[:percent_sigdig] || 2
434
448
  if max_value.to_i == 0
435
449
  percent = 0
436
450
  else
437
451
  percent = ((used_value.to_f / max_value.to_f) * 100)
438
452
  end
439
- percent_label = ((used_value.nil? || max_value.to_f == 0.0) ? "n/a" : "#{percent.round(2)}%").rjust(6, ' ')
453
+ percent_label = ((used_value.nil? || max_value.to_f == 0.0) ? "n/a" : "#{percent.round(percent_sigdig)}%").rjust(6, ' ')
440
454
  bar_display = ""
441
455
  if percent > 100
442
456
  max_bars.times { bars << "|" }
@@ -674,7 +688,7 @@ module Morpheus::Cli::PrintHelper
674
688
  else
675
689
  # so let's use the passed in column definitions instead of the raw data properties
676
690
  # columns = options[:include_fields]
677
- new_columns = []
691
+ new_columns = {}
678
692
  options[:include_fields].each do |f|
679
693
  matching_column = nil
680
694
  # column definitions vary right now, array of symbols/strings/hashes or perhaps a single hash
@@ -692,7 +706,7 @@ module Morpheus::Cli::PrintHelper
692
706
  matching_column = columns[matching_key]
693
707
  end
694
708
  end
695
- new_columns << (matching_column ? matching_column : f)
709
+ new_columns[f] = matching_column ? matching_column : f
696
710
  end
697
711
  columns = new_columns
698
712
  end
@@ -1072,6 +1086,7 @@ module Morpheus::Cli::PrintHelper
1072
1086
  column_defs.each do |column_def|
1073
1087
  label = column_def.label
1074
1088
  value = column_def.display_method.call(obj)
1089
+ value = value.is_a?(String) ? value : JSON.fast_generate(value)
1075
1090
  # value = get_object_value(obj, column_def)
1076
1091
  if do_quotes
1077
1092
  cells << quote_csv_value(value)
@@ -508,7 +508,7 @@ module Morpheus::Cli::ProvisioningHelper
508
508
  if name_prompt['name'].nil? && !options[:name_required]
509
509
  break
510
510
  else
511
- if instances_interface.get({name: name_prompt['name']})['instances'].empty?
511
+ if instances_interface.list({name: name_prompt['name']})['instances'].empty?
512
512
  instance_name = name_prompt['name']
513
513
  else
514
514
  print_red_alert "Name must be unique"
@@ -696,7 +696,7 @@ module Morpheus::Cli::ProvisioningHelper
696
696
  # prompt for service plan
697
697
  plan_id = nil
698
698
  service_plan = nil
699
- service_plans_json = @instances_interface.service_plans({zoneId: cloud_id, layoutId: layout['id'], siteId: group_id})
699
+ service_plans_json = instances_interface.service_plans({zoneId: cloud_id, layoutId: layout['id'], siteId: group_id})
700
700
  service_plans = service_plans_json["plans"]
701
701
  if locked_fields.include?('plan.id')
702
702
  plan_id = options[:options]['plan']['id'] rescue nil
@@ -764,7 +764,7 @@ module Morpheus::Cli::ProvisioningHelper
764
764
  # pluck out the resourcePoolId option type to prompt for
765
765
  resource_pool_option_type = option_type_list.find {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
766
766
  option_type_list = option_type_list.reject {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
767
- resource_pool_options = @options_interface.options_for_source('zonePools', {groupId: group_id, siteId: group_id, zoneId: cloud_id, cloudId: cloud_id, instanceTypeId: instance_type['id'], planId: service_plan["id"], layoutId: layout["id"]})['data']
767
+ resource_pool_options = options_interface.options_for_source('zonePools', {groupId: group_id, siteId: group_id, zoneId: cloud_id, cloudId: cloud_id, instanceTypeId: instance_type['id'], planId: service_plan["id"], layoutId: layout["id"]})['data']
768
768
  resource_pool = resource_pool_options.find {|opt| opt['id'] == options[:resource_pool].to_i} if options[:resource_pool]
769
769
 
770
770
  if resource_pool
@@ -1409,7 +1409,7 @@ module Morpheus::Cli::ProvisioningHelper
1409
1409
  if plan_info['addVolumes']
1410
1410
  volume_index = current_volumes.size
1411
1411
  has_another_volume = options[:options] && options[:options]["dataVolume#{volume_index}"]
1412
- add_another_volume = has_another_volume || (!no_prompt && Morpheus::Cli::OptionTypes.confirm("Add data volume?"))
1412
+ add_another_volume = has_another_volume || (!no_prompt && Morpheus::Cli::OptionTypes.confirm("Add data volume?", {:default => false}))
1413
1413
  while add_another_volume do
1414
1414
  #puts "Configure Data #{volume_index} Volume"
1415
1415
 
@@ -0,0 +1,246 @@
1
+ require 'morpheus/cli/mixins/print_helper'
2
+ # Provides common finder methods for VDI Pool management commands
3
+ module Morpheus::Cli::VdiHelper
4
+
5
+ def self.included(klass)
6
+ klass.send :include, Morpheus::Cli::PrintHelper
7
+ end
8
+
9
+ ## VDI Pools
10
+
11
+ def vdi_pools_interface
12
+ raise "#{self.class} has not defined @vdi_pools_interface" if @vdi_pools_interface.nil?
13
+ @vdi_pools_interface
14
+ end
15
+
16
+ def vdi_pool_object_key
17
+ 'vdiPool'
18
+ end
19
+
20
+ def vdi_pool_list_key
21
+ 'vdiPools'
22
+ end
23
+
24
+ def find_vdi_pool_by_name_or_id(val)
25
+ if val.to_s =~ /\A\d{1,}\Z/
26
+ return find_vdi_pool_by_id(val)
27
+ else
28
+ return find_vdi_pool_by_name(val)
29
+ end
30
+ end
31
+
32
+ def find_vdi_pool_by_id(id)
33
+ begin
34
+ json_response = vdi_pools_interface.get(id.to_i)
35
+ return json_response[vdi_pool_object_key]
36
+ rescue RestClient::Exception => e
37
+ if e.response && e.response.code == 404
38
+ print_red_alert "VDI Pool not found by id '#{id}'"
39
+ else
40
+ raise e
41
+ end
42
+ end
43
+ end
44
+
45
+ def find_vdi_pool_by_name(name)
46
+ json_response = vdi_pools_interface.list({name: name.to_s})
47
+ vdi_pools = json_response[vdi_pool_list_key]
48
+ if vdi_pools.empty?
49
+ print_red_alert "VDI Pool not found by name '#{name}'"
50
+ return nil
51
+ elsif vdi_pools.size > 1
52
+ print_red_alert "#{vdi_pools.size} VDI Pools found by name '#{name}'"
53
+ print_error "\n"
54
+ puts_error as_pretty_table(vdi_pools, [:id, :name], {color:red})
55
+ print_red_alert "Try using ID instead"
56
+ print_error reset,"\n"
57
+ return nil
58
+ else
59
+ return vdi_pools[0]
60
+ end
61
+ end
62
+
63
+ def format_vdi_pool_status(vdi_pool, return_color=cyan)
64
+ out = ""
65
+ status_string = vdi_pool['status'].to_s.downcase
66
+ if status_string
67
+ if ['available'].include?(status_string)
68
+ out << "#{green}#{status_string.upcase}"
69
+ elsif ['unavailable'].include?(status_string)
70
+ out << "#{red}#{status_string.upcase}"
71
+ else
72
+ out << "#{return_color}#{status_string.upcase}"
73
+ end
74
+ end
75
+ out + return_color
76
+ end
77
+
78
+ ## VDI Allocations
79
+
80
+ def vdi_allocations_interface
81
+ raise "#{self.class} has not defined @vdi_allocations_interface" if @vdi_allocations_interface.nil?
82
+ @vdi_allocations_interface
83
+ end
84
+
85
+ def vdi_allocation_object_key
86
+ 'vdiAllocation'
87
+ end
88
+
89
+ def vdi_allocation_list_key
90
+ 'vdiAllocations'
91
+ end
92
+
93
+ def find_vdi_allocation_by_id(id)
94
+ begin
95
+ json_response = vdi_allocations_interface.get(id.to_i)
96
+ return json_response[vdi_allocation_object_key]
97
+ rescue RestClient::Exception => e
98
+ if e.response && e.response.code == 404
99
+ print_red_alert "VDI Allocation not found by id '#{id}'"
100
+ else
101
+ raise e
102
+ end
103
+ end
104
+ end
105
+
106
+ def format_vdi_allocation_status(vdi_allocation, return_color=cyan)
107
+ out = ""
108
+ status_string = vdi_allocation['status'].to_s.downcase
109
+ if status_string
110
+ if ['available'].include?(status_string)
111
+ out << "#{green}#{status_string.upcase}"
112
+ # elsif ['preparing'].include?(status_string)
113
+ # out << "#{yellow}#{status_string.upcase}"
114
+ # elsif ['reserved', 'shutdown'].include?(status_string)
115
+ # out << "#{yellow}#{status_string.upcase}"
116
+ elsif ['failed'].include?(status_string)
117
+ out << "#{red}#{status_string.upcase}"
118
+ else
119
+ out << "#{return_color}#{status_string.upcase}"
120
+ end
121
+ end
122
+ out + return_color
123
+ end
124
+
125
+ def get_available_vdi_apps(refresh=false)
126
+ if !@available_vdi_apps || refresh
127
+ @available_vdi_apps = @vdi_apps_interface.list({max:-1})['vdiApps'] # || []
128
+ end
129
+ return @available_vdi_apps
130
+ end
131
+
132
+ def get_vdi_app_by_name_or_code(name)
133
+ return get_available_vdi_apps().find { |z| z['name'].downcase == name.downcase || z['code'].downcase == name.downcase}
134
+ end
135
+
136
+ ## VDI Apps
137
+
138
+ def vdi_apps_interface
139
+ raise "#{self.class} has not defined @vdi_apps_interface" if @vdi_apps_interface.nil?
140
+ @vdi_apps_interface
141
+ end
142
+
143
+ def vdi_app_object_key
144
+ 'vdiApp'
145
+ end
146
+
147
+ def vdi_app_list_key
148
+ 'vdiApps'
149
+ end
150
+
151
+ def find_vdi_app_by_name_or_id(val)
152
+ if val.to_s =~ /\A\d{1,}\Z/
153
+ return find_vdi_app_by_id(val)
154
+ else
155
+ return find_vdi_app_by_name(val)
156
+ end
157
+ end
158
+
159
+ def find_vdi_app_by_id(id)
160
+ begin
161
+ json_response = vdi_apps_interface.get(id.to_i)
162
+ return json_response[vdi_app_object_key]
163
+ rescue RestClient::Exception => e
164
+ if e.response && e.response.code == 404
165
+ print_red_alert "VDI App not found by id '#{id}'"
166
+ else
167
+ raise e
168
+ end
169
+ end
170
+ end
171
+
172
+ def find_vdi_app_by_name(name)
173
+ json_response = vdi_apps_interface.list({name: name.to_s})
174
+ vdi_apps = json_response[vdi_app_list_key]
175
+ if vdi_apps.empty?
176
+ print_red_alert "VDI App not found by name '#{name}'"
177
+ return nil
178
+ elsif vdi_apps.size > 1
179
+ print_red_alert "#{vdi_apps.size} VDI App found by name '#{name}'"
180
+ print_error "\n"
181
+ puts_error as_pretty_table(vdi_apps, {"ID" => 'id', "NAME" => 'name'}, {color:red})
182
+ print_red_alert "Try using ID instead"
183
+ print_error reset,"\n"
184
+ return nil
185
+ else
186
+ return vdi_apps[0]
187
+ end
188
+ end
189
+
190
+
191
+ ## VDI Gateways
192
+
193
+ def vdi_gateways_interface
194
+ raise "#{self.class} has not defined @vdi_gateways_interface" if @vdi_gateways_interface.nil?
195
+ @vdi_gateways_interface
196
+ end
197
+
198
+ def vdi_gateway_object_key
199
+ 'vdiGateway'
200
+ end
201
+
202
+ def vdi_gateway_list_key
203
+ 'vdiGateways'
204
+ end
205
+
206
+ def find_vdi_gateway_by_name_or_id(val)
207
+ if val.to_s =~ /\A\d{1,}\Z/
208
+ return find_vdi_gateway_by_id(val)
209
+ else
210
+ return find_vdi_gateway_by_name(val)
211
+ end
212
+ end
213
+
214
+ def find_vdi_gateway_by_id(id)
215
+ begin
216
+ json_response = vdi_gateways_interface.get(id.to_i)
217
+ return json_response[vdi_gateway_object_key]
218
+ rescue RestClient::Exception => e
219
+ if e.response && e.response.code == 404
220
+ print_red_alert "VDI Gateway not found by id '#{id}'"
221
+ else
222
+ raise e
223
+ end
224
+ end
225
+ end
226
+
227
+ def find_vdi_gateway_by_name(name)
228
+ json_response = vdi_gateways_interface.list({name: name.to_s})
229
+ vdi_gateways = json_response[vdi_gateway_list_key]
230
+ if vdi_gateways.empty?
231
+ print_red_alert "VDI Gateway not found by name '#{name}'"
232
+ return nil
233
+ elsif vdi_gateways.size > 1
234
+ print_red_alert "#{vdi_gateways.size} VDI Gateway found by name '#{name}'"
235
+ print_error "\n"
236
+ puts_error as_pretty_table(vdi_gateways, {"ID" => 'id', "NAME" => 'name'}, {color:red})
237
+ print_red_alert "Try using ID instead"
238
+ print_error reset,"\n"
239
+ return nil
240
+ else
241
+ return vdi_gateways[0]
242
+ end
243
+ end
244
+
245
+
246
+ end