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.
- 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 +40 -10
- 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
|