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
@@ -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)