morpheus-cli 5.5.1.4 → 5.5.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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/lib/morpheus/api/api_client.rb +25 -0
  4. data/lib/morpheus/api/archive_buckets_interface.rb +1 -1
  5. data/lib/morpheus/api/body_io.rb +22 -0
  6. data/lib/morpheus/api/catalog_item_types_interface.rb +5 -1
  7. data/lib/morpheus/api/clients_interface.rb +41 -0
  8. data/lib/morpheus/api/clouds_interface.rb +21 -0
  9. data/lib/morpheus/api/instances_interface.rb +8 -1
  10. data/lib/morpheus/api/integrations_interface.rb +30 -0
  11. data/lib/morpheus/api/library_instance_types_interface.rb +15 -3
  12. data/lib/morpheus/api/network_pool_server_types_interface.rb +9 -0
  13. data/lib/morpheus/api/plugins_interface.rb +22 -0
  14. data/lib/morpheus/api/roles_interface.rb +20 -1
  15. data/lib/morpheus/api/security_package_types_interface.rb +9 -0
  16. data/lib/morpheus/api/security_packages_interface.rb +9 -0
  17. data/lib/morpheus/api/security_scans_interface.rb +9 -0
  18. data/lib/morpheus/api/servers_interface.rb +17 -17
  19. data/lib/morpheus/api/storage_providers_interface.rb +1 -1
  20. data/lib/morpheus/api/virtual_images_interface.rb +1 -23
  21. data/lib/morpheus/cli/cli_command.rb +81 -7
  22. data/lib/morpheus/cli/commands/apps.rb +28 -2
  23. data/lib/morpheus/cli/commands/archives_command.rb +2 -2
  24. data/lib/morpheus/cli/commands/blueprints_command.rb +16 -0
  25. data/lib/morpheus/cli/commands/catalog_item_types_command.rb +34 -2
  26. data/lib/morpheus/cli/commands/clients_command.rb +338 -0
  27. data/lib/morpheus/cli/commands/clouds.rb +127 -1
  28. data/lib/morpheus/cli/commands/clusters.rb +42 -12
  29. data/lib/morpheus/cli/commands/curl_command.rb +114 -135
  30. data/lib/morpheus/cli/commands/hosts.rb +108 -11
  31. data/lib/morpheus/cli/commands/instances.rb +115 -14
  32. data/lib/morpheus/cli/commands/integrations_command.rb +215 -4
  33. data/lib/morpheus/cli/commands/invoices_command.rb +20 -11
  34. data/lib/morpheus/cli/commands/jobs_command.rb +299 -190
  35. data/lib/morpheus/cli/commands/library_cluster_layouts_command.rb +16 -2
  36. data/lib/morpheus/cli/commands/library_container_scripts_command.rb +14 -0
  37. data/lib/morpheus/cli/commands/library_container_templates_command.rb +131 -48
  38. data/lib/morpheus/cli/commands/library_container_types_command.rb +17 -4
  39. data/lib/morpheus/cli/commands/library_instance_types_command.rb +85 -7
  40. data/lib/morpheus/cli/commands/library_layouts_command.rb +32 -1
  41. data/lib/morpheus/cli/commands/library_option_lists_command.rb +30 -18
  42. data/lib/morpheus/cli/commands/library_option_types_command.rb +31 -14
  43. data/lib/morpheus/cli/commands/library_spec_templates_command.rb +14 -0
  44. data/lib/morpheus/cli/commands/library_upgrades_command.rb +2 -2
  45. data/lib/morpheus/cli/commands/network_pool_server_types.rb +20 -0
  46. data/lib/morpheus/cli/commands/network_pool_servers_command.rb +55 -158
  47. data/lib/morpheus/cli/commands/network_pools_command.rb +49 -23
  48. data/lib/morpheus/cli/commands/networks_command.rb +262 -45
  49. data/lib/morpheus/cli/commands/plugins.rb +213 -0
  50. data/lib/morpheus/cli/commands/price_sets_command.rb +40 -10
  51. data/lib/morpheus/cli/commands/prices_command.rb +17 -5
  52. data/lib/morpheus/cli/commands/processes_command.rb +2 -1
  53. data/lib/morpheus/cli/commands/remote.rb +7 -10
  54. data/lib/morpheus/cli/commands/roles.rb +924 -335
  55. data/lib/morpheus/cli/commands/search_command.rb +2 -0
  56. data/lib/morpheus/cli/commands/security_groups.rb +72 -84
  57. data/lib/morpheus/cli/commands/security_package_types.rb +32 -0
  58. data/lib/morpheus/cli/commands/security_packages.rb +84 -0
  59. data/lib/morpheus/cli/commands/security_scans.rb +107 -0
  60. data/lib/morpheus/cli/commands/service_plans_command.rb +16 -14
  61. data/lib/morpheus/cli/commands/subnets_command.rb +15 -1
  62. data/lib/morpheus/cli/commands/tasks.rb +34 -1
  63. data/lib/morpheus/cli/commands/tenants_command.rb +1 -1
  64. data/lib/morpheus/cli/commands/user_settings_command.rb +11 -2
  65. data/lib/morpheus/cli/commands/users.rb +50 -9
  66. data/lib/morpheus/cli/commands/virtual_images.rb +14 -0
  67. data/lib/morpheus/cli/commands/workflows.rb +14 -0
  68. data/lib/morpheus/cli/mixins/accounts_helper.rb +6 -5
  69. data/lib/morpheus/cli/mixins/infrastructure_helper.rb +79 -0
  70. data/lib/morpheus/cli/mixins/jobs_helper.rb +4 -5
  71. data/lib/morpheus/cli/mixins/library_helper.rb +2 -0
  72. data/lib/morpheus/cli/mixins/logs_helper.rb +3 -0
  73. data/lib/morpheus/cli/mixins/monitoring_helper.rb +1 -1
  74. data/lib/morpheus/cli/mixins/print_helper.rb +29 -4
  75. data/lib/morpheus/cli/mixins/provisioning_helper.rb +38 -9
  76. data/lib/morpheus/cli/mixins/rest_command.rb +106 -8
  77. data/lib/morpheus/cli/mixins/secondary_rest_command.rb +6 -2
  78. data/lib/morpheus/cli/option_types.rb +94 -25
  79. data/lib/morpheus/cli/version.rb +1 -1
  80. data/lib/morpheus/formatters.rb +10 -1
  81. metadata +15 -2
@@ -28,6 +28,14 @@ class Morpheus::Cli::Tasks
28
28
  opts.on('-t', '--type x,y,z', Array, "Filter by task type code(s)") do |val|
29
29
  params['taskTypeCodes'] = val
30
30
  end
31
+
32
+ opts.on('-l', '--labels LABEL', String, "Filter by labels, can match any of the values") do |val|
33
+ add_query_parameter(params, 'labels', parse_labels(val))
34
+ end
35
+ opts.on('--all-labels LABEL', String, "Filter by labels, must match all of the values") do |val|
36
+ add_query_parameter(params, 'allLabels', parse_labels(val))
37
+ end
38
+
31
39
  build_standard_list_options(opts, options)
32
40
  opts.footer = "List tasks."
33
41
  end
@@ -125,6 +133,8 @@ class Morpheus::Cli::Tasks
125
133
  "Name" => 'name',
126
134
  "Code" => 'code',
127
135
  "Type" => lambda {|it| it['taskType']['name'] },
136
+ "Labels" => lambda {|it| format_list(it['labels'], '', 3) rescue '' },
137
+ "Visibility" => 'visibility',
128
138
  "Execute Target" => lambda {|it|
129
139
  if it['executeTarget'] == 'local'
130
140
  git_info = []
@@ -252,6 +262,7 @@ class Morpheus::Cli::Tasks
252
262
  task_name = nil
253
263
  task_code = nil
254
264
  task_type_name = nil
265
+ task_visibility = nil
255
266
  optparse = Morpheus::Cli::OptionParser.new do |opts|
256
267
  opts.banner = subcommand_usage("[name] -t TASK_TYPE")
257
268
  opts.on( '-t', '--type TASK_TYPE', "Task Type" ) do |val|
@@ -259,6 +270,12 @@ class Morpheus::Cli::Tasks
259
270
  end
260
271
  opts.on('--name NAME', String, "Task Name" ) do |val|
261
272
  task_name = val
273
+ end
274
+ opts.on('--visibility VISIBILITY', String, "Task Visibility" ) do |val|
275
+ task_visibility = val
276
+ end
277
+ opts.on('-l', '--labels [LIST]', String, "Labels") do |val|
278
+ options[:options]['labels'] = parse_labels(val)
262
279
  end
263
280
  opts.on('--code CODE', String, "Task Code" ) do |val|
264
281
  task_code = val
@@ -412,6 +429,13 @@ class Morpheus::Cli::Tasks
412
429
  return 1
413
430
  end
414
431
 
432
+ # Visibility
433
+ if task_visibility != nil
434
+ payload['task']['visibility'] = task_visibility
435
+ else
436
+ payload['task']['visibility'] = 'private'
437
+ end
438
+
415
439
  payload['task']['taskType'] = {"id" => task_type['id'], "code" => task_type['code']}
416
440
 
417
441
 
@@ -630,6 +654,12 @@ class Morpheus::Cli::Tasks
630
654
  opts.on('--name NAME', String, "Task Name" ) do |val|
631
655
  options[:options]['name'] = val
632
656
  end
657
+ opts.on('--visibility VISIBILITY', String, "Task Visibility" ) do |val|
658
+ options[:options]['visibility'] = val
659
+ end
660
+ opts.on('-l', '--labels [LIST]', String, "Labels") do |val|
661
+ options[:options]['labels'] = parse_labels(val)
662
+ end
633
663
  opts.on('--code CODE', String, "Task Code" ) do |val|
634
664
  options[:options]['code'] = val
635
665
  end
@@ -1175,7 +1205,10 @@ class Morpheus::Cli::Tasks
1175
1205
  {"ID" => lambda {|it| it['id'] } },
1176
1206
  {"NAME" => lambda {|it| it['name'] } },
1177
1207
  {"TYPE" => lambda {|it| it['taskType']['name'] ? it['taskType']['name'] : it['type'] } },
1178
- {"CREATED" => lambda {|it| format_local_dt(it['dateCreated']) } },
1208
+ {"LABELS" => lambda {|it| format_list(it['labels'], '', 3) rescue '' }},
1209
+ {"VISIBILITY" => lambda {|it| it['visibility'] } },
1210
+ {"CREATED" => lambda {|it| format_local_dt(it['dateCreated']) } }
1211
+
1179
1212
  # {"UPDATED" => lambda {|it| format_local_dt(it['lastUpdated']) } },
1180
1213
  ]
1181
1214
  if opts[:include_fields]
@@ -245,7 +245,7 @@ EOT
245
245
  options = {}
246
246
  optparse = Morpheus::Cli::OptionParser.new do |opts|
247
247
  opts.banner = subcommand_usage("[tenant]")
248
- opts.on('--remove-resources [on|off]', ['on','off'], "Remove Infrastructure. Default is off.") do |val|
248
+ opts.on('--remove-resources [on|off]', ['on','off'], "Remove Associated Instances. Default is off.") do |val|
249
249
  params[:removeResources] = val.nil? ? 'on' : val
250
250
  end
251
251
  build_standard_remove_options(opts, options)
@@ -79,6 +79,7 @@ EOT
79
79
  "First Name" => lambda {|it| it['firstName'] },
80
80
  "Last Name" => lambda {|it| it['lastName'] },
81
81
  "Email" => lambda {|it| it['email'] },
82
+ "Theme" => lambda {|it| it['activeTheme'] ? it['activeTheme'] : '' },
82
83
  "Avatar" => lambda {|it| it['avatar'] ? it['avatar'].split('/').last : '' },
83
84
  "Notifications" => lambda {|it| format_boolean(it['receiveNotifications']) },
84
85
  "Linux Username" => lambda {|it| it['linuxUsername'] },
@@ -102,8 +103,8 @@ EOT
102
103
  "USERNAME" => lambda {|it| it['username'] },
103
104
  "ACCESS TOKEN" => lambda {|it| it['maskedAccessToken'] },
104
105
  "REFRESH TOKEN" => lambda {|it| it['maskedRefreshToken'] },
105
- "EXPIRATION" => lambda {|it| format_local_dt(it['expiration']) },
106
- "TTL" => lambda {|it| it['expiration'] ? (format_duration(it['expiration']) rescue '') : '' }
106
+ "ACCESS EXPIRATION" => lambda {|it| format_local_dt(it['expiration']) },
107
+ "ACCESS TTL" => lambda {|it| it['expiration'] ? (format_duration(it['expiration']) rescue '') : '' }
107
108
  }
108
109
  print cyan
109
110
  puts as_pretty_table(access_tokens, cols)
@@ -807,6 +808,14 @@ EOT
807
808
  {'switch' => 'change-password', 'fieldName' => 'password', 'fieldLabel' => 'Password', 'type' => 'password', 'description' => 'Change user credentials to use a new password'},
808
809
  {'fieldName' => 'avatar', 'fieldLabel' => 'Avatar', 'type' => 'file', 'description' => 'Local filepath of image file to upload as user avatar'},
809
810
  {'fieldName' => 'desktopBackground', 'fieldLabel' => 'Desktop Background', 'type' => 'file', 'description' => 'Local filepath of image file to upload as user desktop background'},
811
+ {'switch' => 'theme', 'fieldName' => 'activeTheme', 'fieldLabel' => 'Theme', 'type' => 'select', 'optionSource' => lambda {|api_client, api_params|
812
+ begin
813
+ api_client.options_for_source("themes", api_params)['data']
814
+ rescue => ex
815
+ Morpheus::Logging::DarkPrinter.puts "Failed to load options for themes. Exception: (#{ex.class}) '#{ex.message}'" if Morpheus::Logging.debug?
816
+ [{"name" => "Default", "value" => "default"}, {"name" => "Dark Mode", "value" => "darkMode"}]
817
+ end
818
+ }, 'description' => 'Active Theme to use for the UI, default or darkMode.'},
810
819
  # api cannot yet modify isUsing2fa
811
820
  # {'switch' => '2fa', 'fieldName' => 'isUsing2fa', 'fieldLabel' => '2FA Enabled', 'type' => 'checkbox', 'description' => 'Enable or Disable 2FA for your user.'}
812
821
  ]
@@ -129,15 +129,15 @@ class Morpheus::Cli::Users
129
129
  opts.on('-g','--global', "Global (All Tenants). Find users across all tenants. Default is your own tenant only.") do
130
130
  options[:global] = true
131
131
  end
132
- opts.on('-p','--permissions', "Display Permissions") do |val|
132
+ opts.on('-p','--permissions', "Display Permissions [deprecated]") do |val|
133
133
  options[:include_features_access] = true
134
134
  params['includeAccess'] = true
135
135
  end
136
- opts.on(nil,'--feature-access', "Display Permissions") do |val|
136
+ opts.add_hidden_option('-p,')
137
+ opts.on(nil,'--feature-access', "Display Feature Access") do |val|
137
138
  options[:include_features_access] = true
138
139
  params['includeAccess'] = true
139
140
  end
140
- opts.add_hidden_option('--feature-access')
141
141
  opts.on(nil,'--group-access', "Display Group Access") do
142
142
  options[:include_sites_access] = true
143
143
  params['includeAccess'] = true
@@ -162,6 +162,22 @@ class Morpheus::Cli::Users
162
162
  options[:include_personas_access] = true
163
163
  params['includeAccess'] = true
164
164
  end
165
+ opts.on(nil,'--vdi-pool-access', "Display VDI Pool Access") do
166
+ options[:include_vdi_pools_access] = true
167
+ params['includeAccess'] = true
168
+ end
169
+ opts.on(nil,'--report-type-access', "Display Report Type Access") do
170
+ options[:include_report_types_access] = true
171
+ params['includeAccess'] = true
172
+ end
173
+ opts.on(nil,'--workflow-access', "Display Workflow Access") do
174
+ options[:include_task_sets_access] = true
175
+ params['includeAccess'] = true
176
+ end
177
+ opts.on(nil,'--task-access', "Display Task Access") do
178
+ options[:include_tasks_access] = true
179
+ params['includeAccess'] = true
180
+ end
165
181
  opts.on(nil,'--all', "Display All Access Lists") do
166
182
  options[:include_features_access] = true
167
183
  options[:include_sites_access] = true
@@ -170,6 +186,10 @@ class Morpheus::Cli::Users
170
186
  options[:include_app_templates_access] = true
171
187
  options[:include_catalog_item_types_access] = true
172
188
  options[:include_personas_access] = true
189
+ options[:include_vdi_pools_access] = true
190
+ options[:include_report_types_access] = true
191
+ options[:include_task_sets_access] = true
192
+ options[:include_tasks_access] = true
173
193
  params['includeAccess'] = true
174
194
  end
175
195
  opts.on(nil, '--hide-none-access', "Hide records with 'none' access") do
@@ -185,6 +205,7 @@ EOT
185
205
  verify_args!(args:args, optparse:optparse, min:1)
186
206
  connect(options)
187
207
  id_list = parse_id_list(args)
208
+ params.merge!(parse_query_options(options))
188
209
  return run_command_for_each_arg(id_list) do |arg|
189
210
  _get(arg, params, options)
190
211
  end
@@ -244,15 +265,24 @@ EOT
244
265
  puts yellow,"No permissions found.",reset
245
266
  end
246
267
  else
247
- available_field_options = {'features' => 'Feature', 'sites' => 'Group', 'zones' => 'Cloud', 'instance_types' => 'Instance Type',
248
- 'app_templates' => 'Blueprint', 'catalog_item_types' => 'Catalog Item Type', 'personas' => 'Persona', 'vdi_pools' => 'VDI Pool', 'report_types' => 'Report Type'}
268
+ available_field_options = {
269
+ 'features' => 'Feature', 'sites' => 'Group', 'zones' => 'Cloud', 'instance_types' => 'Instance Type',
270
+ 'app_templates' => 'Blueprint', 'report_types' => 'Report Type', 'personas' => 'Persona',
271
+ 'catalog_item_types' => 'Catalog Item Type', 'vdi_pools' => 'VDI Pool', 'task_sets' => 'Workflow', 'tasks' => 'Task'
272
+ }
273
+
274
+ if is_tenant_account
275
+ available_field_options.delete("sites")
276
+ else
277
+ available_field_options.delete("zones")
278
+ end
279
+
249
280
  available_field_options.each do |field, label|
250
- if !(field == 'sites' && is_tenant_account) && options["include_#{field}_access".to_sym]
251
- access = user['access'][field.split('_').enum_for(:each_with_index).collect {|word, idx| idx == 0 ? word : word.capitalize}.join]
281
+ if options["include_#{field}_access".to_sym]
282
+ access = user['access'][field.to_s.camelcase] || []
252
283
  access = access.reject {|it| it['access'] == 'none'} if options[:hide_none_access]
253
284
 
254
285
  if field == "features"
255
- # print_h2 "Permissions", options
256
286
  print_h2 "#{label} Access", options
257
287
  else
258
288
  print_h2 "#{label} Access", options
@@ -366,7 +396,18 @@ EOT
366
396
 
367
397
  print_h1 "User Permissions: #{user['username']}", options
368
398
 
369
- available_field_options = {'features' => 'Feature', 'sites' => 'Group', 'zones' => 'Cloud', 'instance_types' => 'Instance Type', 'app_templates' => 'Blueprint', 'catalog_item_types' => 'Catalog Item Type', 'vdi_pools' => 'VDI Pool', 'report_types' => 'Report Type','personas' => 'Persona'}
399
+ available_field_options = {
400
+ 'features' => 'Feature', 'sites' => 'Group', 'zones' => 'Cloud', 'instance_types' => 'Instance Type',
401
+ 'app_templates' => 'Blueprint', 'report_types' => 'Report Type', 'personas' => 'Persona',
402
+ 'catalog_item_types' => 'Catalog Item Type', 'vdi_pools' => 'VDI Pool', 'task_sets' => 'Workflow', 'tasks' => 'Task'
403
+ }
404
+
405
+ if is_tenant_account
406
+ available_field_options.reject! {|k| k == 'sites'}
407
+ else
408
+ available_field_options.reject! {|k| k == 'zones'}
409
+ end
410
+
370
411
  available_field_options.each do |field, label|
371
412
  if !(field == 'sites' && is_tenant_account)
372
413
  access = json_response['access'][field.split('_').enum_for(:each_with_index).collect {|word, idx| idx == 0 ? word : word.capitalize}.join]
@@ -42,6 +42,12 @@ class Morpheus::Cli::VirtualImages
42
42
  opts.on('--synced', "Synced Images" ) do
43
43
  options[:filterType] = 'Synced'
44
44
  end
45
+ opts.on('-l', '--labels LABEL', String, "Filter by labels, can match any of the values") do |val|
46
+ add_query_parameter(params, 'labels', parse_labels(val))
47
+ end
48
+ opts.on('--all-labels LABEL', String, "Filter by labels, must match all of the values") do |val|
49
+ add_query_parameter(params, 'allLabels', parse_labels(val))
50
+ end
45
51
  opts.on('--tags Name=Value',String, "Filter by tags (metadata name value pairs).") do |val|
46
52
  val.split(",").each do |value_pair|
47
53
  k,v = value_pair.strip.split("=")
@@ -101,6 +107,7 @@ class Morpheus::Cli::VirtualImages
101
107
  virtual_image_column_definitions = {
102
108
  "ID" => 'id',
103
109
  "Name" => 'name',
110
+ "Labels" => lambda {|it| format_list(it['labels'], '', 3) rescue '' },
104
111
  "Type" => lambda {|it|
105
112
  # yick, api should return the type with every virtualImage
106
113
  image_type = virtual_image_type_for_name_or_code(it['imageType'])
@@ -197,6 +204,7 @@ EOT
197
204
  description_cols = {
198
205
  "ID" => 'id',
199
206
  "Name" => 'name',
207
+ "Labels" => lambda {|it| format_list(it['labels']) },
200
208
  "Type" => lambda {|it| image_type_display },
201
209
  "Operating System" => lambda {|it| it['osType'] ? it['osType']['name'] : "" },
202
210
  "Storage" => lambda {|it| !image['storageProvider'].nil? ? image['storageProvider']['name'] : 'Default' },
@@ -302,6 +310,9 @@ EOT
302
310
  tenants_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
303
311
  end
304
312
  end
313
+ opts.on('-l', '--labels [LIST]', String, "Labels") do |val|
314
+ options[:options]['labels'] = parse_labels(val)
315
+ end
305
316
  opts.on('--tags LIST', String, "Tags in the format 'name:value, name:value'. This will add and remove tags.") do |val|
306
317
  options[:tags] = val
307
318
  end
@@ -440,6 +451,9 @@ EOT
440
451
  tenants_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
441
452
  end
442
453
  end
454
+ opts.on('-l', '--labels [LIST]', String, "Labels") do |val|
455
+ options[:options]['labels'] = parse_labels(val)
456
+ end
443
457
  opts.on('--tags LIST', String, "Metadata tags in the format 'name:value, name:value'") do |val|
444
458
  options[:tags] = val
445
459
  end
@@ -40,6 +40,12 @@ class Morpheus::Cli::Workflows
40
40
  end
41
41
  params['type'] = workflow_type
42
42
  end
43
+ opts.on('-l', '--labels LABEL', String, "Filter by labels, can match any of the values") do |val|
44
+ add_query_parameter(params, 'labels', parse_labels(val))
45
+ end
46
+ opts.on('--all-labels LABEL', String, "Filter by labels, must match all of the values") do |val|
47
+ add_query_parameter(params, 'allLabels', parse_labels(val))
48
+ end
43
49
  build_standard_list_options(opts, options)
44
50
  opts.footer = "List workflows."
45
51
  end
@@ -93,6 +99,9 @@ class Morpheus::Cli::Workflows
93
99
  opts.on("--name NAME", String, "Name for workflow") do |val|
94
100
  params['name'] = val
95
101
  end
102
+ opts.on('-l', '--labels [LIST]', String, "Labels") do |val|
103
+ options[:options]['labels'] = parse_labels(val)
104
+ end
96
105
  opts.on("--description DESCRIPTION", String, "Description of workflow") do |val|
97
106
  params['description'] = val
98
107
  end
@@ -341,6 +350,7 @@ class Morpheus::Cli::Workflows
341
350
  description_cols = {
342
351
  "ID" => 'id',
343
352
  "Name" => 'name',
353
+ "Labels" => lambda {|it| format_list(it['labels'], '', 3) rescue '' },
344
354
  "Description" => 'description',
345
355
  "Type" => lambda {|workflow| format_workflow_type(workflow) },
346
356
  "Platform" => lambda {|it| format_platform(it['platform']) },
@@ -407,6 +417,9 @@ class Morpheus::Cli::Workflows
407
417
  opts.on("--name NAME", String, "New name for workflow") do |val|
408
418
  params['name'] = val
409
419
  end
420
+ opts.on('-l', '--labels [LIST]', String, "Labels") do |val|
421
+ options[:options]['labels'] = parse_labels(val)
422
+ end
410
423
  opts.on("--description DESCRIPTION", String, "Description of workflow") do |val|
411
424
  params['description'] = val
412
425
  end
@@ -762,6 +775,7 @@ class Morpheus::Cli::Workflows
762
775
  columns = [
763
776
  {"ID" => lambda {|workflow| workflow['id'] } },
764
777
  {"NAME" => lambda {|workflow| workflow['name'] } },
778
+ {"LABELS" => lambda {|it| format_list(it['labels'], '', 3) rescue '' }},
765
779
  {"DESCRIPTION" => lambda {|workflow| workflow['description'] } },
766
780
  {"TYPE" => lambda {|workflow| format_workflow_type(workflow) } },
767
781
  {"TASKS" => lambda {|workflow|
@@ -389,18 +389,19 @@ module Morpheus::Cli::AccountsHelper
389
389
  end
390
390
 
391
391
  def get_access_color(access)
392
- access ||= 'none'
392
+ access ||= 'default'
393
393
  if access == 'none'
394
394
  # maybe reset instead of white?
395
395
  white
396
- elsif access == 'read'
397
- cyan
398
- else
396
+ elsif access.include? 'full'
399
397
  green
398
+ else
399
+ cyan
400
400
  end
401
401
  end
402
402
 
403
403
  def get_access_string(access, return_color=cyan)
404
+ access ||= 'default'
404
405
  get_access_color(access) + access.to_s + return_color.to_s
405
406
  # access ||= 'none'
406
407
  # if access == 'none'
@@ -469,7 +470,7 @@ module Morpheus::Cli::AccountsHelper
469
470
  end
470
471
  # ok build out string
471
472
  out = ""
472
- access_color = get_access_color(access)
473
+ access_color = get_access_color(access || 'default')
473
474
  out << access_color if access_color
474
475
  out << padded_value
475
476
  out << reset if access_color
@@ -479,4 +479,83 @@ module Morpheus::Cli::InfrastructureHelper
479
479
  return {success:true, data: record_ids}
480
480
  end
481
481
 
482
+ def network_pool_server_list_column_definitions(options)
483
+ {
484
+ "ID" => 'id',
485
+ "Name" => lambda {|it| it['name'] },
486
+ "Type" => lambda {|it| it['type'] ? it['type']['name'] : '' },
487
+ "URL" => lambda {|it| it['serviceUrl'] },
488
+ #"Pools" => lambda {|it| it['pools'] ? anded_list(it['pools'].collect {|p| p['name'] }, 3) : '' },
489
+ "Enabled" => lambda {|it| format_boolean(it['enabled']) },
490
+ "Status" => lambda {|it| format_network_pool_server_status(it) },
491
+ "Date Created" => lambda {|it| format_local_dt(it['dateCreated']) },
492
+ "Last Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
493
+ }
494
+ end
495
+
496
+ def network_pool_server_column_definitions(options)
497
+ {
498
+ "ID" => 'id',
499
+ "Name" => lambda {|it| it['name'] },
500
+ "Type" => lambda {|it| it['type'] ? it['type']['name'] : '' },
501
+ "URL" => lambda {|it| it['serviceUrl'] },
502
+ "App ID" => lambda {|it| it['config'] ? it['config']['appId'] : nil },
503
+ "Credentials" => lambda {|it| it['credential'] ? (it['credential']['type'] == 'local' ? '(Local)' : it['credential']['name']) : nil },
504
+ "Username" => lambda {|it| it['serviceUsername'] },
505
+ "Password" => lambda {|it| it['servicePassword'] },
506
+ "Throttle Rate" => lambda {|it| it['serviceThrottleRate'] },
507
+ "Disable SSL SNI" => lambda {|it| format_boolean it['ignoreSsl'] },
508
+ "Inventory Existing" => lambda {|it| format_boolean(it['config'] ? it['config']['inventoryExisting'] : nil) },
509
+ "IP Mode" => lambda {|it| it['serviceMode'] },
510
+ "Network Filter" => lambda {|it| it['networkFilter'] },
511
+ "Zone Filter" => lambda {|it| it['zoneFilter'] },
512
+ "Tenant Match" => lambda {|it| it['tenantMatch'] },
513
+ "Extra Attributes" => lambda {|it| it['config'] ? it['config']['extraAttributes'] : nil },
514
+ "Enabled" => lambda {|it| format_boolean(it['enabled']) },
515
+ "Status" => lambda {|it| format_network_pool_server_status(it) },
516
+ #"Pools" => lambda {|it| it['pools'] ? anded_list(it['pools'].collect {|p| p['name'] }, 3) : '' },
517
+ "Date Created" => lambda {|it| format_local_dt(it['dateCreated']) },
518
+ "Last Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
519
+ }
520
+ end
521
+
522
+ def format_network_pool_server_status(network_pool_server, return_color=cyan)
523
+ out = ""
524
+ status_string = network_pool_server['status']
525
+ if status_string.nil? || status_string.empty? || status_string == "unknown"
526
+ out << "#{white}UNKNOWN#{network_pool_server['statusMessage'] ? "#{return_color} - #{network_pool_server['statusMessage']}" : ''}#{return_color}"
527
+ # elsif network_pool_server['enabled'] == false
528
+ # out << "#{red}DISABLED#{network_pool_server['statusMessage'] ? "#{return_color} - #{network_pool_server['statusMessage']}" : ''}#{return_color}"
529
+ elsif status_string == 'ok'
530
+ out << "#{green}#{status_string.upcase}#{return_color}"
531
+ elsif status_string == 'error' || status_string == 'offline'
532
+ out << "#{red}#{status_string ? status_string.upcase : 'N/A'}#{network_pool_server['statusMessage'] ? "#{return_color} - #{network_pool_server['statusMessage']}" : ''}#{return_color}"
533
+ else
534
+ out << "#{yellow}#{status_string.upcase}#{return_color}"
535
+ end
536
+ out
537
+ end
538
+
539
+ def network_pool_server_type_list_column_definitions(options)
540
+ {
541
+ "ID" => 'id',
542
+ "Name" => 'name',
543
+ "Code" => 'code',
544
+ }
545
+ end
546
+
547
+ def network_pool_server_type_column_definitions(options)
548
+ {
549
+ "ID" => 'id',
550
+ "Name" => 'name',
551
+ "Code" => 'code',
552
+ # "Integration Code" => 'integrationCode',
553
+ "Description" => 'description',
554
+ "Enabled" => lambda {|it| format_boolean(it['enabled']) },
555
+ "Selectable" => lambda {|it| format_boolean(it['selectable']) },
556
+ "Plugin" => lambda {|it| format_boolean(it['isPlugin']) },
557
+ "Embedded" => lambda {|it| format_boolean(it['isEmbedded']) },
558
+ }
559
+ end
560
+
482
561
  end
@@ -79,22 +79,21 @@ module Morpheus::Cli::JobsHelper
79
79
 
80
80
  if process_data[:output] && process_data[:output].strip.length > 0
81
81
  print_h2 "Output"
82
- print process['output']
82
+ print process['output'].to_s.strip
83
+ print reset,"\n"
83
84
  end
84
85
  if process_data[:error] && process_data[:error].strip.length > 0
85
86
  print_h2 "Error"
86
- print process['message'] || process['error']
87
+ print (process['message'] || process['error']).to_s.strip
87
88
  print reset,"\n"
88
89
  end
89
-
90
90
 
91
91
  if process['events'] && !process['events'].empty?
92
92
  print_h2 "Process Events", options
93
93
  print_process_events(process['events'], options)
94
94
  end
95
- else
96
- print reset,"\n"
97
95
  end
96
+ print reset,"\n"
98
97
  return 0, nil
99
98
  end
100
99
 
@@ -59,6 +59,7 @@ module Morpheus::Cli::LibraryHelper
59
59
  {"NAME" => lambda {|instance_type| instance_type['name'] } },
60
60
  {"CODE" => lambda {|instance_type| instance_type['code'] } },
61
61
  {"TECHNOLOGY" => lambda {|instance_type| format_instance_type_technology(instance_type) } },
62
+ {"LABELS" => lambda {|instance_type| format_list(instance_type['labels'], '', 3) } },
62
63
  {"CATEGORY" => lambda {|instance_type| instance_type['category'].to_s.capitalize } },
63
64
  {"FEATURED" => lambda {|instance_type| format_boolean instance_type['featured'] } },
64
65
  {"OWNER" => lambda {|instance_type| instance_type['account'] ? instance_type['account']['name'] : '' } },
@@ -169,6 +170,7 @@ module Morpheus::Cli::LibraryHelper
169
170
  {"NAME" => lambda {|it| it['name'] } },
170
171
  {"SHORT NAME" => lambda {|it| it['shortName'] } },
171
172
  {"VERSION" => lambda {|it| it['containerVersion'] } },
173
+ {"LABELS" => lambda {|it| format_list(it['labels'], '', 3) } },
172
174
  {"CATEGORY" => lambda {|it| it['category'] } },
173
175
  {"OWNER" => lambda {|it| it['account'] ? it['account']['name'] : '' } }
174
176
  ]
@@ -47,6 +47,9 @@ module Morpheus::Cli::LogsHelper
47
47
  table_color = options.key?(:color) ? options[:color] : cyan
48
48
  term_width = current_terminal_width()
49
49
  message_col_width = current_terminal_width() - (show_object ? 56 : 36)
50
+ if options[:reverse]
51
+ log_records.reverse!
52
+ end
50
53
  log_records.each do |log_entry|
51
54
  log_level = format_log_level(log_entry['level'], table_color, 6)
52
55
  out << table_color if table_color
@@ -823,7 +823,7 @@ module Morpheus::Cli::MonitoringHelper
823
823
  # Apps
824
824
 
825
825
  monitor_app_list = nil
826
- monitor_app_ids = nil
826
+ monitor_app_ids = []
827
827
  if params['apps'].nil?
828
828
  still_prompting = true
829
829
  while still_prompting
@@ -714,7 +714,13 @@ module Morpheus::Cli::PrintHelper
714
714
  #
715
715
  def as_pretty_table(data, columns, options={})
716
716
  data = [data].flatten
717
-
717
+ if options[:reverse]
718
+ if data.is_a?(Array)
719
+ data.reverse!
720
+ elsif data.is_a?(Hash)
721
+ data.values.each {|v| v.reverse! if v.is_a?(Array) }
722
+ end
723
+ end
718
724
  # support --fields x,y,z and --all-fields or --fields all
719
725
  all_fields = data.first ? data.first.keys : []
720
726
  #todo: support --raw-fields meh, not really needed..
@@ -1106,7 +1112,13 @@ module Morpheus::Cli::PrintHelper
1106
1112
  newline = options[:csv_newline] || options[:newline] || "\n"
1107
1113
  include_header = options[:csv_no_header] ? false : true
1108
1114
  do_quotes = options[:csv_quotes] || options[:quotes]
1109
-
1115
+ if options[:reverse]
1116
+ if data.is_a?(Array)
1117
+ data.reverse!
1118
+ elsif data.is_a?(Hash)
1119
+ data.values.each {|v| v.reverse! if v.is_a?(Array) }
1120
+ end
1121
+ end
1110
1122
  if options[:include_fields]
1111
1123
  data = transform_data_for_field_options(data, options, object_key)
1112
1124
  if data.is_a?(Hash)
@@ -1134,7 +1146,7 @@ module Morpheus::Cli::PrintHelper
1134
1146
  if data.is_a?(Hash)
1135
1147
  data = data[object_key]
1136
1148
  else
1137
- Morpheus::Logging::DarkPrinter.puts "as_csv() expects data as an to fetch object key '#{object_key}' from, #{records.class}." if Morpheus::Logging.debug?
1149
+ Morpheus::Logging::DarkPrinter.puts "as_csv() expects data as an to fetch object key '#{object_key}' from, #{data.class}." if Morpheus::Logging.debug?
1138
1150
  end
1139
1151
  end
1140
1152
  end
@@ -1216,7 +1228,13 @@ module Morpheus::Cli::PrintHelper
1216
1228
  if !data
1217
1229
  return "null" # "No data"
1218
1230
  end
1219
-
1231
+ if options[:reverse]
1232
+ if data.is_a?(Array)
1233
+ data.reverse!
1234
+ elsif data.is_a?(Hash)
1235
+ data.values.each {|v| v.reverse! if v.is_a?(Array) }
1236
+ end
1237
+ end
1220
1238
  if options[:include_fields]
1221
1239
  data = transform_data_for_field_options(data, options, object_key)
1222
1240
  end
@@ -1236,6 +1254,13 @@ module Morpheus::Cli::PrintHelper
1236
1254
  if !data
1237
1255
  return "null" # "No data"
1238
1256
  end
1257
+ if options[:reverse]
1258
+ if data.is_a?(Array)
1259
+ data.reverse!
1260
+ elsif data.is_a?(Hash)
1261
+ data.values.each {|v| v.reverse! if v.is_a?(Array) }
1262
+ end
1263
+ end
1239
1264
  if options[:include_fields]
1240
1265
  data = transform_data_for_field_options(data, options, object_key)
1241
1266
  end