morpheus-cli 5.3.0 → 5.3.1.1

Sign up to get free protection for your applications and to get access to all the features.
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 +0 -6
  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 +7 -4
  133. data/lib/morpheus/cli/commands/standard/history_command.rb +4 -5
  134. data/lib/morpheus/cli/commands/standard/man_command.rb +4 -5
  135. data/lib/morpheus/cli/credentials.rb +4 -11
  136. data/lib/morpheus/cli/environments_command.rb +1 -1
  137. data/lib/morpheus/cli/execute_schedules_command.rb +3 -3
  138. data/lib/morpheus/cli/hosts.rb +253 -232
  139. data/lib/morpheus/cli/image_builder_command.rb +6 -6
  140. data/lib/morpheus/cli/instance_types.rb +1 -1
  141. data/lib/morpheus/cli/instances.rb +196 -186
  142. data/lib/morpheus/cli/integrations_command.rb +1155 -42
  143. data/lib/morpheus/cli/invoices_command.rb +75 -67
  144. data/lib/morpheus/cli/key_pairs.rb +2 -2
  145. data/lib/morpheus/cli/library_container_scripts_command.rb +1 -1
  146. data/lib/morpheus/cli/library_container_templates_command.rb +1 -1
  147. data/lib/morpheus/cli/library_container_types_command.rb +6 -6
  148. data/lib/morpheus/cli/library_instance_types_command.rb +4 -4
  149. data/lib/morpheus/cli/library_layouts_command.rb +5 -5
  150. data/lib/morpheus/cli/library_option_lists_command.rb +4 -4
  151. data/lib/morpheus/cli/library_option_types_command.rb +4 -4
  152. data/lib/morpheus/cli/library_upgrades_command.rb +6 -6
  153. data/lib/morpheus/cli/license.rb +2 -2
  154. data/lib/morpheus/cli/load_balancers.rb +1 -1
  155. data/lib/morpheus/cli/login.rb +10 -1
  156. data/lib/morpheus/cli/mixins/option_source_helper.rb +15 -16
  157. data/lib/morpheus/cli/mixins/print_helper.rb +33 -18
  158. data/lib/morpheus/cli/mixins/provisioning_helper.rb +4 -4
  159. data/lib/morpheus/cli/mixins/vdi_helper.rb +246 -0
  160. data/lib/morpheus/cli/network_domains_command.rb +2 -2
  161. data/lib/morpheus/cli/network_routers_command.rb +22 -9
  162. data/lib/morpheus/cli/networks_command.rb +2 -2
  163. data/lib/morpheus/cli/option_types.rb +39 -34
  164. data/lib/morpheus/cli/policies_command.rb +0 -1
  165. data/lib/morpheus/cli/power_schedules_command.rb +3 -3
  166. data/lib/morpheus/cli/preseed_scripts_command.rb +1 -1
  167. data/lib/morpheus/cli/remote.rb +2 -2
  168. data/lib/morpheus/cli/reports_command.rb +5 -2
  169. data/lib/morpheus/cli/roles.rb +224 -64
  170. data/lib/morpheus/cli/security_group_rules.rb +1 -1
  171. data/lib/morpheus/cli/service_plans_command.rb +4 -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
@@ -30,15 +30,15 @@ class Morpheus::Cli::ImageBuilderCommand
30
30
 
31
31
  def connect(opts)
32
32
  @api_client = establish_remote_appliance_connection(opts)
33
- @image_builder_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).image_builder
33
+ @image_builder_interface = @api_client.image_builder
34
34
  @image_builds_interface = @image_builder_interface.image_builds
35
35
  @boot_scripts_interface = @image_builder_interface.boot_scripts
36
36
  @preseed_scripts_interface = @image_builder_interface.preseed_scripts
37
- @groups_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).groups
38
- @clouds_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).clouds
39
- @instances_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).instances
40
- @instance_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).instance_types
41
- @options_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).options
37
+ @groups_interface = @api_client.groups
38
+ @clouds_interface = @api_client.clouds
39
+ @instances_interface = @api_client.instances
40
+ @instance_types_interface = @api_client.instance_types
41
+ @options_interface = @api_client.options
42
42
  @active_group_id = Morpheus::Cli::Groups.active_groups[@appliance_name]
43
43
  end
44
44
 
@@ -17,7 +17,7 @@ class Morpheus::Cli::InstanceTypes
17
17
 
18
18
  def connect(opts)
19
19
  @api_client = establish_remote_appliance_connection(opts)
20
- @instance_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).instance_types
20
+ @instance_types_interface = @api_client.instance_types
21
21
  end
22
22
 
23
23
  def handle(args)
@@ -84,6 +84,16 @@ class Morpheus::Cli::Instances
84
84
  opts.on('--status STATUS', "Filter by status i.e. provisioning,running,starting,stopping") do |val|
85
85
  params['status'] = (params['status'] || []) + val.to_s.split(',').collect {|s| s.strip }.select {|s| s != "" }
86
86
  end
87
+ opts.on( '--type CODE', String, "Filter by Instance Type code" ) do |val|
88
+ # commas used in names a lot so use --plan one --plan two
89
+ params['instanceType'] ||= []
90
+ params['instanceType'] << val
91
+ end
92
+ opts.on( '--environment CODE', String, "Filter by Environment code(s)" ) do |val|
93
+ # commas used in names a lot so use --plan one --plan two
94
+ params['environment'] ||= []
95
+ params['environment'] << val
96
+ end
87
97
  opts.on('--pending-removal', "Include instances pending removal.") do
88
98
  options[:showDeleted] = true
89
99
  end
@@ -120,8 +130,9 @@ class Morpheus::Cli::Instances
120
130
  end
121
131
  opts.on('-a', '--details', "Display all details: plan, stats, etc" ) do
122
132
  options[:details] = true
133
+ params['details'] = true # get more data from server this way
123
134
  end
124
- build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
135
+ build_standard_list_options(opts, options)
125
136
  opts.footer = "List instances."
126
137
  end
127
138
  optparse.parse!(args)
@@ -130,159 +141,150 @@ class Morpheus::Cli::Instances
130
141
  options[:phrase] = args.join(" ")
131
142
  end
132
143
  connect(options)
133
- begin
134
- params.merge!(parse_list_options(options))
135
- group = options[:group] ? find_group_by_name_or_id_for_provisioning(options[:group]) : nil
136
- if group
137
- params['siteId'] = group['id']
138
- end
139
144
 
140
- # argh, this doesn't work because group_id is required for options/clouds
141
- # cloud = options[:cloud] ? find_cloud_by_name_or_id_for_provisioning(group_id, options[:cloud]) : nil
142
- cloud = options[:cloud] ? find_zone_by_name_or_id(nil, options[:cloud]) : nil
143
- if cloud
144
- params['zoneId'] = cloud['id']
145
- end
145
+ params.merge!(parse_list_options(options))
146
+ group = options[:group] ? find_group_by_name_or_id_for_provisioning(options[:group]) : nil
147
+ if group
148
+ params['siteId'] = group['id']
149
+ end
146
150
 
147
- host = options[:host] ? find_host_by_name_or_id(options[:host]) : options[:host]
148
- if host
149
- params['serverId'] = host['id']
150
- end
151
+ # argh, this doesn't work because group_id is required for options/clouds
152
+ # cloud = options[:cloud] ? find_cloud_by_name_or_id_for_provisioning(group_id, options[:cloud]) : nil
153
+ cloud = options[:cloud] ? find_zone_by_name_or_id(nil, options[:cloud]) : nil
154
+ if cloud
155
+ params['zoneId'] = cloud['id']
156
+ end
151
157
 
152
- account = nil
153
- #todo: user = find_available_user_option(owner_id)
158
+ host = options[:host] ? find_host_by_name_or_id(options[:host]) : options[:host]
159
+ if host
160
+ params['serverId'] = host['id']
161
+ end
154
162
 
155
- if options[:owner]
156
- created_by_ids = find_all_user_ids(account ? account['id'] : nil, options[:owner])
157
- return if created_by_ids.nil?
158
- params['createdBy'] = created_by_ids
159
- params['ownerId'] = created_by_ids # 4.2.1+
163
+ account = nil
164
+ #todo: user = find_available_user_option(owner_id)
165
+
166
+ if options[:owner]
167
+ created_by_ids = find_all_user_ids(account ? account['id'] : nil, options[:owner])
168
+ return if created_by_ids.nil?
169
+ params['createdBy'] = created_by_ids
170
+ params['ownerId'] = created_by_ids # 4.2.1+
171
+ end
172
+
173
+ params['showDeleted'] = true if options[:showDeleted]
174
+ params['deleted'] = true if options[:deleted]
175
+ params['labels'] = options[:labels] if options[:labels]
176
+ if options[:tags]
177
+ options[:tags].each do |k,v|
178
+ params['tags.' + k] = v
160
179
  end
180
+ end
161
181
 
162
- params['showDeleted'] = true if options[:showDeleted]
163
- params['deleted'] = true if options[:deleted]
164
- params['labels'] = options[:labels] if options[:labels]
165
- if options[:tags]
166
- options[:tags].each do |k,v|
167
- params['tags.' + k] = v
182
+ @instances_interface.setopts(options)
183
+ if options[:dry_run]
184
+ print_dry_run @instances_interface.dry.list(params)
185
+ return 0
186
+ end
187
+ json_response = @instances_interface.list(params)
188
+ all_stats = json_response['stats'] || {}
189
+ # merge stats into each record just to be nice...
190
+ if options[:include_fields] || options[:all_fields]
191
+ if json_response['instances']
192
+ if all_stats
193
+ json_response['instances'].each do |it|
194
+ it['stats'] ||= all_stats[it['id'].to_s] || all_stats[it['id']]
195
+ end
168
196
  end
169
197
  end
198
+ end
199
+ render_response(json_response, options, "instances") do
200
+ instances = json_response['instances']
170
201
 
171
- @instances_interface.setopts(options)
172
- if options[:dry_run]
173
- print_dry_run @instances_interface.dry.list(params)
174
- return 0
202
+ title = "Morpheus Instances"
203
+ subtitles = []
204
+ if group
205
+ subtitles << "Group: #{group['name']}".strip
175
206
  end
176
- json_response = @instances_interface.list(params)
177
- if options[:json]
178
- puts as_json(json_response, options, "instances")
179
- return 0
180
- elsif options[:yaml]
181
- puts as_yaml(json_response, options, "instances")
182
- return 0
183
- elsif options[:csv]
184
- # merge stats to be nice here..
185
- if json_response['instances']
186
- all_stats = json_response['stats'] || {}
187
- if all_stats
188
- json_response['instances'].each do |it|
189
- it['stats'] ||= all_stats[it['id'].to_s] || all_stats[it['id']]
207
+ if cloud
208
+ subtitles << "Cloud: #{cloud['name']}".strip
209
+ end
210
+ if host
211
+ subtitles << "Host: #{host['name']}".strip
212
+ end
213
+ if options[:owner]
214
+ subtitles << "Created By: #{options[:owner]}"
215
+ end
216
+ subtitles += parse_list_subtitles(options)
217
+ print_h1 title, subtitles, options
218
+ if instances.empty?
219
+ print cyan,"No instances found.",reset,"\n"
220
+ else
221
+ # print_instances_table(instances)
222
+ # server returns stats in a separate key stats => {"id" => {} }
223
+ # the id is a string right now..for some reason..
224
+ all_stats = json_response['stats'] || {}
225
+ if all_stats
226
+ instances.each do |it|
227
+ if !it['stats']
228
+ found_stats = all_stats[it['id'].to_s] || all_stats[it['id']]
229
+ it['stats'] = found_stats # || {}
190
230
  end
191
231
  end
192
232
  end
193
- puts records_as_csv(json_response['instances'], options)
194
- else
195
- instances = json_response['instances']
196
233
 
197
- title = "Morpheus Instances"
198
- subtitles = []
199
- if group
200
- subtitles << "Group: #{group['name']}".strip
201
- end
202
- if cloud
203
- subtitles << "Cloud: #{cloud['name']}".strip
204
- end
205
- if host
206
- subtitles << "Host: #{host['name']}".strip
207
- end
208
- if options[:owner]
209
- subtitles << "Created By: #{options[:owner]}"
210
- end
211
- subtitles += parse_list_subtitles(options)
212
- print_h1 title, subtitles, options
213
- if instances.empty?
214
- print cyan,"No instances found.",reset,"\n"
215
- else
216
- # print_instances_table(instances)
217
- # server returns stats in a separate key stats => {"id" => {} }
218
- # the id is a string right now..for some reason..
219
- all_stats = json_response['stats'] || {}
220
- if all_stats
221
- instances.each do |it|
222
- if !it['stats']
223
- found_stats = all_stats[it['id'].to_s] || all_stats[it['id']]
224
- it['stats'] = found_stats # || {}
225
- end
234
+ rows = instances.collect {|instance|
235
+ stats = instance['stats']
236
+ cpu_usage_str = !stats ? "" : generate_usage_bar((stats['usedCpu'] || stats['cpuUsage']).to_f, 100, {max_bars: 10})
237
+ memory_usage_str = !stats ? "" : generate_usage_bar(stats['usedMemory'], stats['maxMemory'], {max_bars: 10})
238
+ storage_usage_str = !stats ? "" : generate_usage_bar(stats['usedStorage'], stats['maxStorage'], {max_bars: 10})
239
+ if options[:details] || options[:stats]
240
+ if stats['maxMemory'] && stats['maxMemory'].to_i != 0
241
+ memory_usage_str = memory_usage_str + cyan + format_bytes_short(stats['usedMemory']).strip.rjust(8, ' ') + " / " + format_bytes_short(stats['maxMemory']).strip
226
242
  end
227
- end
228
-
229
- rows = instances.collect {|instance|
230
- stats = instance['stats']
231
- cpu_usage_str = !stats ? "" : generate_usage_bar((stats['usedCpu'] || stats['cpuUsage']).to_f, 100, {max_bars: 10})
232
- memory_usage_str = !stats ? "" : generate_usage_bar(stats['usedMemory'], stats['maxMemory'], {max_bars: 10})
233
- storage_usage_str = !stats ? "" : generate_usage_bar(stats['usedStorage'], stats['maxStorage'], {max_bars: 10})
234
- if options[:details] || options[:stats]
235
- if stats['maxMemory'] && stats['maxMemory'].to_i != 0
236
- memory_usage_str = memory_usage_str + cyan + format_bytes_short(stats['usedMemory']).strip.rjust(8, ' ') + " / " + format_bytes_short(stats['maxMemory']).strip
237
- end
238
- if stats['maxStorage'] && stats['maxStorage'].to_i != 0
239
- storage_usage_str = storage_usage_str + cyan + format_bytes_short(stats['usedStorage']).strip.rjust(8, ' ') + " / " + format_bytes_short(stats['maxStorage']).strip
240
- end
243
+ if stats['maxStorage'] && stats['maxStorage'].to_i != 0
244
+ storage_usage_str = storage_usage_str + cyan + format_bytes_short(stats['usedStorage']).strip.rjust(8, ' ') + " / " + format_bytes_short(stats['maxStorage']).strip
241
245
  end
242
- row = {
243
- id: instance['id'],
244
- name: instance['name'],
245
- connection: format_instance_connection_string(instance),
246
- environment: instance['instanceContext'],
247
- user: (instance['owner'] ? (instance['owner']['username'] || instance['owner']['id']) : (instance['createdBy'].is_a?(Hash) ? instance['createdBy']['username'] : instance['createdBy'])),
248
- tenant: (instance['owner'] ? (instance['owner']['username'] || instance['owner']['id']) : (instance['createdBy'].is_a?(Hash) ? instance['createdBy']['username'] : instance['createdBy'])),
249
- nodes: instance['containers'].count,
250
- status: format_instance_status(instance, cyan),
251
- type: instance['instanceType']['name'],
252
- group: instance['group'] ? instance['group']['name'] : nil,
253
- cloud: instance['cloud'] ? instance['cloud']['name'] : nil,
254
- plan: instance['plan'] ? instance['plan']['name'] : '',
255
- version: instance['instanceVersion'] ? instance['instanceVersion'] : '',
256
- created: format_local_dt(instance['dateCreated']),
257
- cpu: cpu_usage_str + cyan,
258
- memory: memory_usage_str + cyan,
259
- storage: storage_usage_str + cyan
260
- }
261
- row
262
- }
263
- columns = [:id, {:name => {:max_width => 50}}, :group, :cloud,
264
- :type, :version, :environment,
265
- {:created => {:display_name => "CREATED"}},
266
- # {:tenant => {:display_name => "TENANT"}},
267
- {:user => {:display_name => "OWNER", :max_width => 20}},
268
- :plan,
269
- :nodes, {:connection => {:max_width => 30}}, :status, :cpu, :memory, :storage]
270
- # custom pretty table columns ... this is handled in as_pretty_table now(),
271
- # todo: remove all these.. and try to always pass rows as the json data itself..
272
- if options[:details] != true
273
- columns.delete(:plan)
274
246
  end
275
- print cyan
276
- print as_pretty_table(rows, columns, options)
277
- print reset
278
- print_results_pagination(json_response)
247
+ row = {
248
+ id: instance['id'],
249
+ name: instance['name'],
250
+ connection: format_instance_connection_string(instance),
251
+ environment: instance['instanceContext'],
252
+ user: (instance['owner'] ? (instance['owner']['username'] || instance['owner']['id']) : (instance['createdBy'].is_a?(Hash) ? instance['createdBy']['username'] : instance['createdBy'])),
253
+ tenant: (instance['owner'] ? (instance['owner']['username'] || instance['owner']['id']) : (instance['createdBy'].is_a?(Hash) ? instance['createdBy']['username'] : instance['createdBy'])),
254
+ nodes: instance['containers'].count,
255
+ status: format_instance_status(instance, cyan),
256
+ type: instance['instanceType']['name'],
257
+ group: instance['group'] ? instance['group']['name'] : nil,
258
+ cloud: instance['cloud'] ? instance['cloud']['name'] : nil,
259
+ plan: instance['plan'] ? instance['plan']['name'] : '',
260
+ version: instance['instanceVersion'] ? instance['instanceVersion'] : '',
261
+ created: format_local_dt(instance['dateCreated']),
262
+ cpu: cpu_usage_str + cyan,
263
+ memory: memory_usage_str + cyan,
264
+ storage: storage_usage_str + cyan
265
+ }
266
+ row
267
+ }
268
+ columns = [:id, {:name => {:max_width => 50}}, :group, :cloud,
269
+ :type, :version, :environment,
270
+ {:created => {:display_name => "CREATED"}},
271
+ # {:tenant => {:display_name => "TENANT"}},
272
+ {:user => {:display_name => "OWNER", :max_width => 20}},
273
+ :plan,
274
+ :nodes, {:connection => {:max_width => 30}}, :status, :cpu, :memory, :storage]
275
+ # custom pretty table columns ... this is handled in as_pretty_table now(),
276
+ # todo: remove all these.. and try to always pass rows as the json data itself..
277
+ if options[:details] != true
278
+ columns.delete(:plan)
279
279
  end
280
- print reset,"\n"
280
+ print cyan
281
+ print as_pretty_table(rows, columns, options)
282
+ print reset
283
+ print_results_pagination(json_response)
281
284
  end
282
- rescue RestClient::Exception => e
283
- print_rest_exception(e, options)
284
- exit 1
285
+ print reset,"\n"
285
286
  end
287
+ return 0, nil
286
288
  end
287
289
 
288
290
  def count(args)
@@ -436,7 +438,7 @@ class Morpheus::Cli::Instances
436
438
  opts.on("--create-backup [on|off]", String, "Automation: Create Backups.") do |val|
437
439
  options[:create_backup] = ['on','true','1',''].include?(val.to_s.downcase) ? 'on' : 'off'
438
440
  end
439
- opts.on("--security-groups LIST", String, "Security Groups, comma sepearated list of security group IDs") do |val|
441
+ opts.on("--security-groups LIST", String, "Security Groups, comma separated list of security group IDs") do |val|
440
442
  options[:security_groups] = val.split(",").collect {|s| s.strip }.select {|s| !s.to_s.empty? }
441
443
  end
442
444
  opts.on('--refresh [SECONDS]', String, "Refresh until status is running,failed. Default interval is #{default_refresh_interval} seconds.") do |val|
@@ -1200,7 +1202,15 @@ class Morpheus::Cli::Instances
1200
1202
  options[:details] = true
1201
1203
  options[:include_containers] = true
1202
1204
  options[:include_scaling] = true
1205
+ options[:include_costs]
1206
+ end
1207
+ opts.on(nil, '--details', "Alias for --all" ) do
1208
+ options[:details] = true
1209
+ options[:include_containers] = true
1210
+ options[:include_scaling] = true
1211
+ options[:include_costs]
1203
1212
  end
1213
+ opts.add_hidden_option('--details')
1204
1214
  opts.on( nil, '--containers', "Display Instance Containers" ) do
1205
1215
  options[:include_containers] = true
1206
1216
  end
@@ -1215,9 +1225,6 @@ class Morpheus::Cli::Instances
1215
1225
  opts.on( nil, '--scaling', "Display Instance Scaling Settings" ) do
1216
1226
  options[:include_scaling] = true
1217
1227
  end
1218
- opts.on( nil, '--costs', "Display Cost and Price" ) do
1219
- options[:include_costs] = true
1220
- end
1221
1228
  opts.on('--refresh [SECONDS]', String, "Refresh until status is running,failed. Default interval is #{default_refresh_interval} seconds.") do |val|
1222
1229
  options[:refresh_until_status] ||= "running,failed"
1223
1230
  if !val.to_s.empty?
@@ -1233,7 +1240,7 @@ class Morpheus::Cli::Instances
1233
1240
  # opts.on( nil, '--lb', "Display Load Balancer Details" ) do
1234
1241
  # options[:include_lb] = true
1235
1242
  # end
1236
- build_common_options(opts, options, [:query, :json, :yaml, :csv, :fields, :dry_run, :remote])
1243
+ build_standard_get_options(opts, options)
1237
1244
  opts.footer = "Get details about an instance.\n" +
1238
1245
  "[instance] is required. This is the name or id of an instance. Supports 1-N [instance] arguments."
1239
1246
  end
@@ -1249,36 +1256,29 @@ class Morpheus::Cli::Instances
1249
1256
  end
1250
1257
  end
1251
1258
 
1252
- def _get(arg, options={})
1253
- begin
1254
- if options[:dry_run]
1255
- @instances_interface.setopts(options)
1256
- if arg.to_s =~ /\A\d{1,}\Z/
1257
- print_dry_run @instances_interface.dry.get(arg.to_i)
1258
- else
1259
- print_dry_run @instances_interface.dry.get({name:arg})
1260
- end
1261
- return
1262
- end
1263
- instance = find_instance_by_name_or_id(arg =~ /\A\d{1,}\Z/ ? arg.to_i : arg)
1264
- @instances_interface.setopts(options)
1265
- json_response = @instances_interface.get(instance['id'])
1266
- if options[:quiet]
1267
- return 0
1268
- end
1269
- if options[:json]
1270
- puts as_json(json_response, options, "instance")
1271
- return 0
1272
- elsif options[:yaml]
1273
- puts as_yaml(json_response, options, "instance")
1274
- return 0
1275
- end
1276
-
1277
- if options[:csv]
1278
- puts records_as_csv([json_response['instance']], options)
1279
- return 0
1280
- end
1259
+ def _get(id, options={})
1260
+ params = {}
1261
+ params.merge!(parse_query_options(options))
1262
+ # Use details=true to get more details from the appliance
1263
+ # if options[:details] || options[:include_containers] || options[:include_scaling]
1264
+ if options[:details] || options[:include_containers] || options[:include_scaling]
1265
+ params['details'] = true
1266
+ end
1267
+ instance = nil
1268
+ if id.to_s !~ /\A\d{1,}\Z/
1269
+ instance = find_instance_by_name_or_id(id)
1270
+ return 1, "Instance not found by name #{id}" if instance.nil?
1271
+ id = instance['id']
1272
+ end
1273
+ if options[:dry_run]
1274
+ print_dry_run @instances_interface.dry.get(id, params)
1275
+ return 0, nil
1276
+ end
1277
+ @instances_interface.setopts(options)
1278
+ json_response = @instances_interface.get(id, params)
1279
+ render_response(json_response, options, "instance") do
1281
1280
  instance = json_response['instance']
1281
+ pricing = instance['instancePrice']
1282
1282
  stats = instance['stats'] || json_response['stats'] || {}
1283
1283
  # load_balancers = json_response['loadBalancers'] || {}
1284
1284
  # metadata tags used to be returned as metadata and are now returned as tags
@@ -1296,7 +1296,12 @@ class Morpheus::Cli::Instances
1296
1296
  # containers are fetched via separate api call
1297
1297
  containers = nil
1298
1298
  if options[:include_containers]
1299
- containers = @instances_interface.containers(instance['id'])['containers']
1299
+ # todo: can use instance['containerDetails'] in api 5.2.7/5.3.2
1300
+ if instance['containerDetails']
1301
+ containers = instance['containerDetails']
1302
+ else
1303
+ containers = @instances_interface.containers(instance['id'])['containers']
1304
+ end
1300
1305
  end
1301
1306
 
1302
1307
  # threshold is fetched via separate api call too
@@ -1330,8 +1335,20 @@ class Morpheus::Cli::Instances
1330
1335
  "Layout" => lambda {|it| it['layout'] ? it['layout']['name'] : '' },
1331
1336
  "Version" => lambda {|it| it['instanceVersion'] },
1332
1337
  "Plan" => lambda {|it| it['plan'] ? it['plan']['name'] : '' },
1333
- # "Cost" => lambda {|it| it['hourlyCost'] ? format_money(it['hourlyCost'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
1334
- # "Price" => lambda {|it| it['hourlyPrice'] ? format_money(it['hourlyPrice'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
1338
+ "Price" => lambda {|it|
1339
+ if pricing
1340
+ pricing['price'] ? format_money(pricing['price'], (pricing['currency'] || 'USD')).to_s + ' per ' + pricing['unit'].to_s : ''
1341
+ elsif it['hourlyPrice']
1342
+ format_money(it['hourlyPrice'], (it['currency'] || 'USD')).to_s + ' per hour'
1343
+ end
1344
+ },
1345
+ "Cost" => lambda {|it|
1346
+ if pricing
1347
+ pricing['cost'] ? format_money(pricing['cost'], (pricing['currency'] || 'USD')).to_s + ' per ' + pricing['unit'].to_s : ''
1348
+ elsif it['hourlyCost']
1349
+ format_money(it['hourlyCost'], (it['currency'] || 'USD')).to_s + ' per hour'
1350
+ end
1351
+ },
1335
1352
  "Environment" => 'instanceContext',
1336
1353
  "Labels" => lambda {|it| labels ? labels.join(',') : '' },
1337
1354
  "Tags" => lambda {|it| tags ? tags.collect {|m| "#{m['name']}: #{m['value']}" }.join(', ') : '' },
@@ -1343,6 +1360,7 @@ class Morpheus::Cli::Instances
1343
1360
  end
1344
1361
  },
1345
1362
  #"Tenant" => lambda {|it| it['tenant'] ? it['tenant']['name'] : '' },
1363
+ "Apps" => lambda {|it| anded_list(it['apps'] ? it['apps'].collect {|app| app['name'] } : [])},
1346
1364
  "Date Created" => lambda {|it| format_local_dt(it['dateCreated']) },
1347
1365
  # "Last Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
1348
1366
  "Power Schedule" => lambda {|it| (it['powerSchedule'] && it['powerSchedule']['type']) ? it['powerSchedule']['type']['name'] : '' },
@@ -1356,12 +1374,17 @@ class Morpheus::Cli::Instances
1356
1374
  }
1357
1375
  description_cols.delete("Labels") if labels.nil? || labels.empty?
1358
1376
  description_cols.delete("Tags") if tags.nil? || tags.empty?
1377
+ description_cols.delete("Apps") if instance['apps'].nil? || instance['apps'].empty?
1359
1378
  description_cols.delete("Power Schedule") if instance['powerSchedule'].nil?
1360
1379
  description_cols.delete("Expire Date") if instance['expireDate'].nil?
1361
1380
  description_cols.delete("Shutdown Date") if instance['shutdownDate'].nil?
1362
1381
  description_cols["Removal Date"] = lambda {|it| format_local_dt(it['removalDate'])} if instance['status'] == 'pendingRemoval'
1363
1382
  description_cols.delete("Last Deployment") if instance['lastDeploy'].nil?
1364
1383
  description_cols.delete("Locked") if instance['locked'] != true
1384
+ price_value = (pricing ? pricing['price'] : instance['hourlyPrice']).to_i
1385
+ cost_value = (pricing ? pricing['cost'] : instance['hourlyCost']).to_i
1386
+ description_cols.delete("Price") if price_value == 0
1387
+ description_cols.delete("Cost") if cost_value == 0 || cost_value == price_value
1365
1388
  #description_cols.delete("Environment") if instance['instanceContext'].nil?
1366
1389
  print_description_list(description_cols, instance)
1367
1390
 
@@ -1393,15 +1416,6 @@ class Morpheus::Cli::Instances
1393
1416
  print_stats_usage(stats)
1394
1417
  end
1395
1418
 
1396
- if options[:include_costs]
1397
- print_h2 "Instance Cost"
1398
- cost_columns = {
1399
- "Cost" => lambda {|it| it['hourlyCost'] ? format_money(it['hourlyCost'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
1400
- "Price" => lambda {|it| it['hourlyPrice'] ? format_money(it['hourlyPrice'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
1401
- }
1402
- print_description_list(cost_columns, instance)
1403
- end
1404
-
1405
1419
  print reset, "\n"
1406
1420
 
1407
1421
  # if options[:include_lb]
@@ -1491,15 +1505,11 @@ class Morpheus::Cli::Instances
1491
1505
  print cyan, "Refreshing in #{options[:refresh_interval] > 1 ? options[:refresh_interval].to_i : options[:refresh_interval]} seconds"
1492
1506
  sleep_with_dots(options[:refresh_interval])
1493
1507
  print "\n"
1494
- _get(arg, options)
1508
+ _get(instance['id'], options)
1495
1509
  end
1496
1510
  end
1497
-
1498
- return 0
1499
- rescue RestClient::Exception => e
1500
- print_rest_exception(e, options)
1501
- exit 1
1502
1511
  end
1512
+ return 0, nil
1503
1513
  end
1504
1514
 
1505
1515
  def list_containers(args)