morpheus-cli 5.5.1.5 → 5.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/lib/morpheus/api/api_client.rb +25 -0
- data/lib/morpheus/api/archive_buckets_interface.rb +1 -1
- data/lib/morpheus/api/body_io.rb +22 -0
- data/lib/morpheus/api/catalog_item_types_interface.rb +5 -1
- data/lib/morpheus/api/clients_interface.rb +41 -0
- data/lib/morpheus/api/clouds_interface.rb +21 -0
- data/lib/morpheus/api/instances_interface.rb +8 -1
- data/lib/morpheus/api/integrations_interface.rb +30 -0
- data/lib/morpheus/api/library_instance_types_interface.rb +15 -3
- data/lib/morpheus/api/network_pool_server_types_interface.rb +9 -0
- data/lib/morpheus/api/plugins_interface.rb +22 -0
- data/lib/morpheus/api/roles_interface.rb +20 -1
- data/lib/morpheus/api/security_package_types_interface.rb +9 -0
- data/lib/morpheus/api/security_packages_interface.rb +9 -0
- data/lib/morpheus/api/security_scans_interface.rb +9 -0
- data/lib/morpheus/api/servers_interface.rb +17 -17
- data/lib/morpheus/api/storage_providers_interface.rb +1 -1
- data/lib/morpheus/api/virtual_images_interface.rb +1 -23
- data/lib/morpheus/cli/cli_command.rb +81 -7
- data/lib/morpheus/cli/commands/apps.rb +28 -2
- data/lib/morpheus/cli/commands/archives_command.rb +2 -2
- data/lib/morpheus/cli/commands/blueprints_command.rb +16 -0
- data/lib/morpheus/cli/commands/catalog_item_types_command.rb +34 -2
- data/lib/morpheus/cli/commands/clients_command.rb +338 -0
- data/lib/morpheus/cli/commands/clouds.rb +127 -1
- data/lib/morpheus/cli/commands/clusters.rb +42 -12
- data/lib/morpheus/cli/commands/curl_command.rb +114 -135
- data/lib/morpheus/cli/commands/hosts.rb +108 -11
- data/lib/morpheus/cli/commands/instances.rb +115 -14
- data/lib/morpheus/cli/commands/integrations_command.rb +215 -4
- data/lib/morpheus/cli/commands/invoices_command.rb +20 -11
- data/lib/morpheus/cli/commands/jobs_command.rb +299 -190
- data/lib/morpheus/cli/commands/library_cluster_layouts_command.rb +16 -2
- data/lib/morpheus/cli/commands/library_container_scripts_command.rb +14 -0
- data/lib/morpheus/cli/commands/library_container_templates_command.rb +131 -48
- data/lib/morpheus/cli/commands/library_container_types_command.rb +17 -4
- data/lib/morpheus/cli/commands/library_instance_types_command.rb +85 -7
- data/lib/morpheus/cli/commands/library_layouts_command.rb +32 -1
- data/lib/morpheus/cli/commands/library_option_lists_command.rb +30 -18
- data/lib/morpheus/cli/commands/library_option_types_command.rb +31 -14
- data/lib/morpheus/cli/commands/library_spec_templates_command.rb +14 -0
- data/lib/morpheus/cli/commands/library_upgrades_command.rb +2 -2
- data/lib/morpheus/cli/commands/network_pool_server_types.rb +20 -0
- data/lib/morpheus/cli/commands/network_pool_servers_command.rb +55 -158
- data/lib/morpheus/cli/commands/network_pools_command.rb +49 -23
- data/lib/morpheus/cli/commands/networks_command.rb +262 -45
- data/lib/morpheus/cli/commands/plugins.rb +213 -0
- data/lib/morpheus/cli/commands/price_sets_command.rb +27 -8
- data/lib/morpheus/cli/commands/prices_command.rb +17 -5
- data/lib/morpheus/cli/commands/processes_command.rb +2 -1
- data/lib/morpheus/cli/commands/remote.rb +7 -10
- data/lib/morpheus/cli/commands/roles.rb +924 -335
- data/lib/morpheus/cli/commands/search_command.rb +2 -0
- data/lib/morpheus/cli/commands/security_groups.rb +72 -84
- data/lib/morpheus/cli/commands/security_package_types.rb +32 -0
- data/lib/morpheus/cli/commands/security_packages.rb +84 -0
- data/lib/morpheus/cli/commands/security_scans.rb +107 -0
- data/lib/morpheus/cli/commands/service_plans_command.rb +16 -14
- data/lib/morpheus/cli/commands/subnets_command.rb +15 -1
- data/lib/morpheus/cli/commands/tasks.rb +34 -1
- data/lib/morpheus/cli/commands/tenants_command.rb +1 -1
- data/lib/morpheus/cli/commands/user_settings_command.rb +11 -2
- data/lib/morpheus/cli/commands/users.rb +50 -9
- data/lib/morpheus/cli/commands/virtual_images.rb +14 -0
- data/lib/morpheus/cli/commands/workflows.rb +14 -0
- data/lib/morpheus/cli/mixins/accounts_helper.rb +6 -5
- data/lib/morpheus/cli/mixins/infrastructure_helper.rb +79 -0
- data/lib/morpheus/cli/mixins/jobs_helper.rb +4 -5
- data/lib/morpheus/cli/mixins/library_helper.rb +2 -0
- data/lib/morpheus/cli/mixins/logs_helper.rb +3 -0
- data/lib/morpheus/cli/mixins/monitoring_helper.rb +1 -1
- data/lib/morpheus/cli/mixins/print_helper.rb +29 -4
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +38 -9
- data/lib/morpheus/cli/mixins/rest_command.rb +106 -8
- data/lib/morpheus/cli/mixins/secondary_rest_command.rb +6 -2
- data/lib/morpheus/cli/option_types.rb +94 -25
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/formatters.rb +10 -1
- 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
|
-
{"
|
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
|
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.
|
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 = {
|
248
|
-
|
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
|
251
|
-
access = user['access'][field.
|
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 = {
|
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 ||= '
|
392
|
+
access ||= 'default'
|
393
393
|
if access == 'none'
|
394
394
|
# maybe reset instead of white?
|
395
395
|
white
|
396
|
-
elsif access
|
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
|
@@ -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, #{
|
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
|