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
@@ -79,6 +79,12 @@ class Morpheus::Cli::Apps
|
|
79
79
|
opts.on('--status STATUS', "Filter by status.") do |val|
|
80
80
|
params['status'] = (params['status'] || []) + val.to_s.split(',').collect {|s| s.strip }.select {|s| s != "" }
|
81
81
|
end
|
82
|
+
opts.on('-l', '--labels LABEL', String, "Filter by labels, can match any of the values") do |val|
|
83
|
+
add_query_parameter(params, 'labels', parse_labels(val))
|
84
|
+
end
|
85
|
+
opts.on('--all-labels LABEL', String, "Filter by labels, must match all of the values") do |val|
|
86
|
+
add_query_parameter(params, 'allLabels', parse_labels(val))
|
87
|
+
end
|
82
88
|
opts.on('-a', '--details', "Display all details: memory and storage usage used / max values." ) do
|
83
89
|
options[:details] = true
|
84
90
|
end
|
@@ -221,6 +227,9 @@ class Morpheus::Cli::Apps
|
|
221
227
|
opts.on( '--name VALUE', String, "Name" ) do |val|
|
222
228
|
options[:name] = val
|
223
229
|
end
|
230
|
+
opts.on('-l', '--labels [LIST]', String, "Labels") do |val|
|
231
|
+
options[:options]['labels'] = parse_labels(val)
|
232
|
+
end
|
224
233
|
opts.on( '--description VALUE', String, "Description" ) do |val|
|
225
234
|
options[:description] = val
|
226
235
|
end
|
@@ -303,7 +312,6 @@ class Morpheus::Cli::Apps
|
|
303
312
|
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Enter a name for this app'}], options[:options])
|
304
313
|
payload['name'] = v_prompt['name']
|
305
314
|
|
306
|
-
|
307
315
|
# Description
|
308
316
|
options[:options]['description'] = options[:description] if options.key?(:description)
|
309
317
|
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'required' => false}], options[:options])
|
@@ -332,7 +340,7 @@ class Morpheus::Cli::Apps
|
|
332
340
|
end
|
333
341
|
if cloud_id
|
334
342
|
cloud = find_cloud_by_name_or_id_for_provisioning(group['id'], cloud_id)
|
335
|
-
|
343
|
+
payload['defaultCloud'] = {'id' => cloud ? cloud['id'] : cloud_id}
|
336
344
|
end
|
337
345
|
|
338
346
|
# Environment
|
@@ -354,6 +362,11 @@ class Morpheus::Cli::Apps
|
|
354
362
|
end
|
355
363
|
# payload['appContext'] = payload['environment'] if payload['environment']
|
356
364
|
|
365
|
+
# Labels
|
366
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'labels', 'fieldLabel' => 'Labels', 'type' => 'text'}], options[:options])
|
367
|
+
payload['labels'] = parse_labels(v_prompt['labels']) unless v_prompt['labels'].to_s.empty?
|
368
|
+
|
369
|
+
# Configure (Tiers and their instances)
|
357
370
|
if !payload['tiers']
|
358
371
|
if payload['blueprintId'] != 'existing'
|
359
372
|
|
@@ -371,6 +384,7 @@ class Morpheus::Cli::Apps
|
|
371
384
|
# tiers are a map, heh, sort them by tierIndex
|
372
385
|
tiers = blueprint["config"]["tiers"] ? blueprint["config"]["tiers"] : (blueprint["tiers"] || {})
|
373
386
|
sorted_tiers = tiers.collect {|k,v| [k,v] }.sort {|a,b| a[1]['tierIndex'] <=> b[1]['tierIndex'] }
|
387
|
+
payload.delete('defaultCloud')
|
374
388
|
sorted_tiers.each do |tier_obj|
|
375
389
|
tier_name = tier_obj[0]
|
376
390
|
tier_config = tier_obj[1]
|
@@ -453,6 +467,8 @@ class Morpheus::Cli::Apps
|
|
453
467
|
instance_prompt_options[:options][:help_field_prefix] = help_field_prefix
|
454
468
|
instance_prompt_options[:locked_fields] = scoped_instance_config['lockedFields']
|
455
469
|
instance_prompt_options[:for_app] = true
|
470
|
+
instance_prompt_options[:skip_labels_prompt] = true
|
471
|
+
# or could do this: instance_prompt_options[:labels] = default_labels
|
456
472
|
# this provisioning helper method handles all (most) of the parsing and prompting
|
457
473
|
scoped_instance_config = Marshal.load( Marshal.dump(scoped_instance_config) )
|
458
474
|
instance_config_payload = prompt_new_instance(instance_prompt_options)
|
@@ -467,6 +483,10 @@ class Morpheus::Cli::Apps
|
|
467
483
|
final_config.delete('groups')
|
468
484
|
final_config.delete('clouds')
|
469
485
|
final_config.delete('lockedFields')
|
486
|
+
final_config.delete('userRemovedFields')
|
487
|
+
# should not need this...
|
488
|
+
final_config.delete(:no_prompt)
|
489
|
+
final_config.delete(:help_field_prefix)
|
470
490
|
# add config to payload
|
471
491
|
payload['tiers'][tier_name]['instances'] ||= []
|
472
492
|
payload['tiers'][tier_name]['instances'] << final_config
|
@@ -682,6 +702,7 @@ class Morpheus::Cli::Apps
|
|
682
702
|
description_cols = {
|
683
703
|
"ID" => 'id',
|
684
704
|
"Name" => 'name',
|
705
|
+
"Labels" => lambda {|it| format_list(it['labels']) rescue '' },
|
685
706
|
"Description" => 'description',
|
686
707
|
"Type" => lambda {|it|
|
687
708
|
if it['type']
|
@@ -810,6 +831,9 @@ class Morpheus::Cli::Apps
|
|
810
831
|
opts.on( '--name VALUE', String, "Name" ) do |val|
|
811
832
|
options[:name] = val
|
812
833
|
end
|
834
|
+
opts.on('-l', '--labels [LIST]', String, "Labels") do |val|
|
835
|
+
options[:options]['labels'] = parse_labels(val)
|
836
|
+
end
|
813
837
|
opts.on( '--description VALUE', String, "Description" ) do |val|
|
814
838
|
options[:description] = val
|
815
839
|
end
|
@@ -2367,6 +2391,7 @@ EOT
|
|
2367
2391
|
{
|
2368
2392
|
id: app['id'],
|
2369
2393
|
name: app['name'],
|
2394
|
+
labels: format_list(app['labels'], '', 3),
|
2370
2395
|
description: app['description'],
|
2371
2396
|
blueprint: app['blueprint'] ? app['blueprint']['name'] : '',
|
2372
2397
|
type: app['type'] ? format_blueprint_type(app['type']) : (format_blueprint_type(app['blueprint'] ? app['blueprint']['type'] : nil)),
|
@@ -2389,6 +2414,7 @@ EOT
|
|
2389
2414
|
columns = [
|
2390
2415
|
:id,
|
2391
2416
|
:name,
|
2417
|
+
:labels,
|
2392
2418
|
# :description,
|
2393
2419
|
:type,
|
2394
2420
|
:blueprint,
|
@@ -973,10 +973,10 @@ class Morpheus::Cli::ArchivesCommand
|
|
973
973
|
|
974
974
|
|
975
975
|
print_h2 "Download URLs"
|
976
|
-
private_download_url = "#{@appliance_url}/api/archives/download/#{CGI::escape(bucket_id)}" + "/#{
|
976
|
+
private_download_url = "#{@appliance_url}/api/archives/download/#{CGI::escape(bucket_id)}" + "/#{escape_filepath(archive_file['filePath'])}".squeeze('/')
|
977
977
|
public_download_url = nil
|
978
978
|
if archive_file['archiveBucket'] && archive_file['archiveBucket']['isPublic']
|
979
|
-
public_download_url = "#{@appliance_url}/public-archives/download/#{CGI::escape(bucket_id)}" + "/#{
|
979
|
+
public_download_url = "#{@appliance_url}/public-archives/download/#{CGI::escape(bucket_id)}" + "/#{escape_filepath(archive_file['filePath'])}".squeeze('/')
|
980
980
|
end
|
981
981
|
print cyan
|
982
982
|
puts "Private URL: #{private_download_url}"
|
@@ -62,6 +62,12 @@ class Morpheus::Cli::BlueprintsCommand
|
|
62
62
|
params['ownerId'] << val
|
63
63
|
end
|
64
64
|
opts.add_hidden_option('--created-by')
|
65
|
+
opts.on('-l', '--labels LABEL', String, "Filter by labels, can match any of the values") do |val|
|
66
|
+
add_query_parameter(params, 'labels', parse_labels(val))
|
67
|
+
end
|
68
|
+
opts.on('--all-labels LABEL', String, "Filter by labels, must match all of the values") do |val|
|
69
|
+
add_query_parameter(params, 'allLabels', parse_labels(val))
|
70
|
+
end
|
65
71
|
build_standard_list_options(opts, options)
|
66
72
|
opts.footer = "List blueprints."
|
67
73
|
end
|
@@ -191,6 +197,9 @@ class Morpheus::Cli::BlueprintsCommand
|
|
191
197
|
opts.on('-t', '--type TYPE', String, "Blueprint Type. Default is morpheus.") do |val|
|
192
198
|
options[:blueprint_type] = parse_blueprint_type(val.to_s)
|
193
199
|
end
|
200
|
+
opts.on('-l', '--labels [LIST]', String, "Labels") do |val|
|
201
|
+
options[:options]['labels'] = parse_labels(val)
|
202
|
+
end
|
194
203
|
build_standard_add_options(opts, options)
|
195
204
|
opts.footer = "Create a new blueprint.\n" +
|
196
205
|
"[name] is required. This is the name of the new blueprint."
|
@@ -258,6 +267,9 @@ class Morpheus::Cli::BlueprintsCommand
|
|
258
267
|
opts.on( '--owner USER', "Owner Username or ID" ) do |val|
|
259
268
|
options[:owner] = val == 'null' ? nil : val
|
260
269
|
end
|
270
|
+
opts.on('-l', '--labels [LIST]', String, "Labels") do |val|
|
271
|
+
options[:options]['labels'] = parse_labels(val)
|
272
|
+
end
|
261
273
|
build_standard_update_options(opts, options)
|
262
274
|
opts.footer = "Update a blueprint.\n" +
|
263
275
|
"[blueprint] is required. This is the name or id of a blueprint."
|
@@ -817,6 +829,7 @@ class Morpheus::Cli::BlueprintsCommand
|
|
817
829
|
options[:name_required] = false
|
818
830
|
options[:instance_type_code] = instance_config['instance']['type'] #instance_type["code"]
|
819
831
|
options[:for_app] = true
|
832
|
+
options[:skip_labels_prompt] = true
|
820
833
|
#options[:options].deep_merge!(specific_config)
|
821
834
|
# this provisioning helper method handles all (most) of the parsing and prompting
|
822
835
|
instance_config_payload = prompt_new_instance(options)
|
@@ -1929,6 +1942,7 @@ class Morpheus::Cli::BlueprintsCommand
|
|
1929
1942
|
{
|
1930
1943
|
id: blueprint['id'],
|
1931
1944
|
name: blueprint['name'],
|
1945
|
+
labels: format_list(blueprint['labels'], '', 3),
|
1932
1946
|
type: blueprint['type'].kind_of?(Hash) ? blueprint['type']['name'] : format_blueprint_type(blueprint['type']),
|
1933
1947
|
description: blueprint['description'],
|
1934
1948
|
category: blueprint['category'],
|
@@ -1947,6 +1961,7 @@ class Morpheus::Cli::BlueprintsCommand
|
|
1947
1961
|
columns = [
|
1948
1962
|
:id,
|
1949
1963
|
:name,
|
1964
|
+
:labels,
|
1950
1965
|
:type,
|
1951
1966
|
:description,
|
1952
1967
|
:category,
|
@@ -2026,6 +2041,7 @@ class Morpheus::Cli::BlueprintsCommand
|
|
2026
2041
|
description_cols = {
|
2027
2042
|
"ID" => 'id',
|
2028
2043
|
"Name" => 'name',
|
2044
|
+
"Labels" => lambda {|it| format_list(it['labels'], '') rescue '' },
|
2029
2045
|
"Type" => lambda {|it| it['type'].kind_of?(Hash) ? it['type']['name'] : it['type'] },
|
2030
2046
|
"Description" => 'description',
|
2031
2047
|
"Category" => 'category',
|
@@ -37,6 +37,12 @@ class Morpheus::Cli::CatalogItemTypesCommand
|
|
37
37
|
opts.on( '--featured [on|off]', String, "Filter by featured" ) do |val|
|
38
38
|
params['featured'] = (val.to_s != 'false' && val.to_s != 'off')
|
39
39
|
end
|
40
|
+
opts.on('-l', '--labels LABEL', String, "Filter by labels, can match any of the values") do |val|
|
41
|
+
add_query_parameter(params, 'labels', parse_labels(val))
|
42
|
+
end
|
43
|
+
opts.on('--all-labels LABEL', String, "Filter by labels, must match all of the values") do |val|
|
44
|
+
add_query_parameter(params, 'allLabels', parse_labels(val))
|
45
|
+
end
|
40
46
|
build_standard_list_options(opts, options)
|
41
47
|
opts.footer = "List catalog item types."
|
42
48
|
end
|
@@ -59,7 +65,7 @@ class Morpheus::Cli::CatalogItemTypesCommand
|
|
59
65
|
if catalog_item_types.empty?
|
60
66
|
print cyan,"No catalog item types found.",reset,"\n"
|
61
67
|
else
|
62
|
-
list_columns =
|
68
|
+
list_columns = catalog_item_type_list_column_definitions.upcase_keys!
|
63
69
|
list_columns.delete("Blueprint")
|
64
70
|
list_columns.delete("Workflow")
|
65
71
|
list_columns.delete("Context")
|
@@ -232,6 +238,9 @@ EOT
|
|
232
238
|
# options[:options]['type'] = val.to_s.downcase
|
233
239
|
# end
|
234
240
|
build_option_type_options(opts, options, add_catalog_item_type_option_types)
|
241
|
+
opts.on('-l', '--labels [LIST]', String, "Labels") do |val|
|
242
|
+
options[:options]['labels'] = parse_labels(val)
|
243
|
+
end
|
235
244
|
opts.on('--logo FILE', String, "Upload a custom logo icon") do |val|
|
236
245
|
filename = val
|
237
246
|
logo_file = nil
|
@@ -386,6 +395,9 @@ EOT
|
|
386
395
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
387
396
|
opts.banner = subcommand_usage("[type] [options]")
|
388
397
|
build_option_type_options(opts, options, update_catalog_item_type_option_types)
|
398
|
+
opts.on('-l', '--labels [LIST]', String, "Labels") do |val|
|
399
|
+
options[:options]['labels'] = parse_labels(val)
|
400
|
+
end
|
389
401
|
opts.on('--logo FILE', String, "Upload a custom logo icon") do |val|
|
390
402
|
filename = val
|
391
403
|
logo_file = nil
|
@@ -549,7 +561,7 @@ EOT
|
|
549
561
|
filename = args[1]
|
550
562
|
logo_file = nil
|
551
563
|
if filename == 'null'
|
552
|
-
|
564
|
+
logo_file = 'null' # clear it
|
553
565
|
else
|
554
566
|
filename = File.expand_path(filename)
|
555
567
|
if !File.exists?(filename)
|
@@ -641,10 +653,30 @@ EOT
|
|
641
653
|
|
642
654
|
private
|
643
655
|
|
656
|
+
def catalog_item_type_list_column_definitions()
|
657
|
+
{
|
658
|
+
"ID" => 'id',
|
659
|
+
"Name" => 'name',
|
660
|
+
"Labels" => lambda {|it| format_list(it['labels'], '', 3) },
|
661
|
+
"Description" => 'description',
|
662
|
+
"Type" => lambda {|it| format_catalog_type(it) },
|
663
|
+
"Blueprint" => lambda {|it| it['blueprint'] ? it['blueprint']['name'] : nil },
|
664
|
+
"Workflow" => lambda {|it| it['workflow'] ? it['workflow']['name'] : nil },
|
665
|
+
"Context" => lambda {|it| it['context'] },
|
666
|
+
# "Content" => lambda {|it| it['content'] },
|
667
|
+
"Enabled" => lambda {|it| format_boolean(it['enabled']) },
|
668
|
+
"Featured" => lambda {|it| format_boolean(it['featured']) },
|
669
|
+
#"Config" => lambda {|it| it['config'] },
|
670
|
+
"Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
671
|
+
"Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
|
672
|
+
}
|
673
|
+
end
|
674
|
+
|
644
675
|
def catalog_item_type_column_definitions()
|
645
676
|
{
|
646
677
|
"ID" => 'id',
|
647
678
|
"Name" => 'name',
|
679
|
+
"Labels" => lambda {|it| format_list(it['labels']) },
|
648
680
|
"Description" => 'description',
|
649
681
|
"Type" => lambda {|it| format_catalog_type(it) },
|
650
682
|
"Blueprint" => lambda {|it| it['blueprint'] ? it['blueprint']['name'] : nil },
|
@@ -0,0 +1,338 @@
|
|
1
|
+
require 'morpheus/cli/cli_command'
|
2
|
+
|
3
|
+
class Morpheus::Cli::ClientsCommand
|
4
|
+
include Morpheus::Cli::CliCommand
|
5
|
+
|
6
|
+
set_command_name :clients
|
7
|
+
set_command_description "View and manage Oath Clients"
|
8
|
+
register_subcommands :list, :get, :add, :update, :remove
|
9
|
+
|
10
|
+
def initialize()
|
11
|
+
#@appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
12
|
+
end
|
13
|
+
|
14
|
+
def connect(opts)
|
15
|
+
@api_client = establish_remote_appliance_connection(opts)
|
16
|
+
@clients_interface = @api_client.clients
|
17
|
+
end
|
18
|
+
|
19
|
+
def handle(args)
|
20
|
+
handle_subcommand(args)
|
21
|
+
end
|
22
|
+
|
23
|
+
def list(args)
|
24
|
+
options = {}
|
25
|
+
params = {}
|
26
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
27
|
+
opts.banner = subcommand_usage()
|
28
|
+
build_standard_list_options(opts, options)
|
29
|
+
opts.footer = "List Oauth Clients."
|
30
|
+
end
|
31
|
+
optparse.parse!(args)
|
32
|
+
connect(options)
|
33
|
+
|
34
|
+
params.merge!(parse_list_options(options))
|
35
|
+
@clients_interface.setopts(options)
|
36
|
+
if options[:dry_run]
|
37
|
+
print_dry_run @clients_interface.dry.list(params)
|
38
|
+
return 0
|
39
|
+
end
|
40
|
+
|
41
|
+
json_response = @clients_interface.list(params)
|
42
|
+
render_response(json_response, options, "clients") do
|
43
|
+
clients = json_response["clients"]
|
44
|
+
if clients.empty?
|
45
|
+
print cyan,"No clients found",reset,"\n"
|
46
|
+
else
|
47
|
+
rows = clients.collect {|client|
|
48
|
+
row = {
|
49
|
+
id: client['id'],
|
50
|
+
client_id: client['clientId'],
|
51
|
+
access_token_seconds: client['accessTokenValiditySeconds'],
|
52
|
+
refresh_token_seconds: client['refreshTokenValiditySeconds']
|
53
|
+
}
|
54
|
+
row
|
55
|
+
}
|
56
|
+
columns = [:id, {:client_id => {:max_width => 50}}, :access_token_seconds, :refresh_token_seconds]
|
57
|
+
print_h1 "Morpheus Clients", [], options
|
58
|
+
print as_pretty_table(rows, columns, options)
|
59
|
+
print reset
|
60
|
+
print_results_pagination(json_response)
|
61
|
+
end
|
62
|
+
print reset,"\n"
|
63
|
+
end
|
64
|
+
return 0, nil
|
65
|
+
end
|
66
|
+
|
67
|
+
def get(args)
|
68
|
+
options = {}
|
69
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
70
|
+
opts.banner = subcommand_usage("[client]")
|
71
|
+
build_standard_get_options(opts, options)
|
72
|
+
opts.footer = "Get details about an oath client.\n" +
|
73
|
+
"[client] is required. This is the name or id of a client."
|
74
|
+
|
75
|
+
end
|
76
|
+
optparse.parse!(args)
|
77
|
+
if args.count < 1
|
78
|
+
puts optparse
|
79
|
+
exit 1
|
80
|
+
end
|
81
|
+
connect(options)
|
82
|
+
begin
|
83
|
+
@clients_interface.setopts(options)
|
84
|
+
if options[:dry_run]
|
85
|
+
if args[0].to_s =~ /\A\d{1,}\Z/
|
86
|
+
print_dry_run @clients_interface.dry.get(args[0])
|
87
|
+
else
|
88
|
+
print_dry_run @clients_interface.dry.list({name: args[0].to_s})
|
89
|
+
end
|
90
|
+
return 0
|
91
|
+
end
|
92
|
+
client = find_client_by_name_or_id(args[0])
|
93
|
+
return 1 if client.nil?
|
94
|
+
json_response = {'client' => client}
|
95
|
+
render_result = render_with_format(json_response, options, 'client')
|
96
|
+
return 0 if render_result
|
97
|
+
|
98
|
+
unless options[:quiet]
|
99
|
+
print_h1 "Client Details"
|
100
|
+
print cyan
|
101
|
+
client_columns = {
|
102
|
+
"ID" => 'id',
|
103
|
+
"Client ID" => 'clientId',
|
104
|
+
"Access Token Validity Seconds" => 'accessTokenValiditySeconds',
|
105
|
+
"Refresh Token Validity Seconds" => 'refreshTokenValiditySeconds'
|
106
|
+
}
|
107
|
+
|
108
|
+
print_description_list(client_columns, client)
|
109
|
+
print reset,"\n"
|
110
|
+
|
111
|
+
end
|
112
|
+
print reset,"\n"
|
113
|
+
return 0
|
114
|
+
rescue RestClient::Exception => e
|
115
|
+
print_rest_exception(e, options)
|
116
|
+
exit 1
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def add(args)
|
121
|
+
options = {}
|
122
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
123
|
+
opts.banner = subcommand_usage("[clientId] [options]")
|
124
|
+
build_option_type_options(opts, options, add_client_option_types)
|
125
|
+
build_common_options(opts, options, [:payload, :options, :json, :dry_run, :remote])
|
126
|
+
opts.footer = "Add New Oauth Client Record."
|
127
|
+
end
|
128
|
+
optparse.parse!(args)
|
129
|
+
if args.count > 1
|
130
|
+
raise_command_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args}\n#{optparse}"
|
131
|
+
end
|
132
|
+
if args[0]
|
133
|
+
options[:options] ||= {}
|
134
|
+
options[:options]['clientId'] ||= args[0]
|
135
|
+
end
|
136
|
+
connect(options)
|
137
|
+
begin
|
138
|
+
# construct payload
|
139
|
+
passed_options = options[:options] ? options[:options].reject {|k,v| k.is_a?(Symbol) } : {}
|
140
|
+
payload = nil
|
141
|
+
if options[:payload]
|
142
|
+
payload = options[:payload]
|
143
|
+
payload.deep_merge!({'client' => passed_options}) unless passed_options.empty?
|
144
|
+
else
|
145
|
+
payload = {
|
146
|
+
'client' => {
|
147
|
+
}
|
148
|
+
}
|
149
|
+
# allow arbitrary -O options
|
150
|
+
payload.deep_merge!({'client' => passed_options}) unless passed_options.empty?
|
151
|
+
# prompt for options
|
152
|
+
params = Morpheus::Cli::OptionTypes.prompt(add_client_option_types, options[:options], @api_client, options[:params])
|
153
|
+
payload.deep_merge!({'client' => params}) unless params.empty?
|
154
|
+
end
|
155
|
+
|
156
|
+
@clients_interface.setopts(options)
|
157
|
+
if options[:dry_run]
|
158
|
+
print_dry_run @clients_interface.dry.create(payload)
|
159
|
+
return
|
160
|
+
end
|
161
|
+
json_response = @clients_interface.create(payload)
|
162
|
+
if options[:json]
|
163
|
+
print JSON.pretty_generate(json_response)
|
164
|
+
print "\n"
|
165
|
+
else
|
166
|
+
display_name = json_response['client'] ? json_response['client']['clientId'] : ''
|
167
|
+
print_green_success "Client #{display_name} added"
|
168
|
+
get([json_response['client']['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
|
169
|
+
end
|
170
|
+
return 0
|
171
|
+
rescue RestClient::Exception => e
|
172
|
+
print_rest_exception(e, options)
|
173
|
+
exit 1
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def update(args)
|
178
|
+
options = {}
|
179
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
180
|
+
opts.banner = subcommand_usage("[clientId] [options]")
|
181
|
+
build_option_type_options(opts, options, client_option_types)
|
182
|
+
build_common_options(opts, options, [:payload, :options, :json, :dry_run, :remote])
|
183
|
+
opts.footer = "Update Oauth Client Record."
|
184
|
+
end
|
185
|
+
optparse.parse!(args)
|
186
|
+
|
187
|
+
if args.count != 1
|
188
|
+
raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args}\n#{optparse}"
|
189
|
+
end
|
190
|
+
|
191
|
+
connect(options)
|
192
|
+
begin
|
193
|
+
|
194
|
+
client = find_client_by_name_or_id(args[0])
|
195
|
+
return 1 if client.nil?
|
196
|
+
|
197
|
+
# construct payload
|
198
|
+
passed_options = options[:options] ? options[:options].reject {|k,v| k.is_a?(Symbol) } : {}
|
199
|
+
payload = nil
|
200
|
+
if options[:payload]
|
201
|
+
payload = options[:payload]
|
202
|
+
payload.deep_merge!({'client' => passed_options}) unless passed_options.empty?
|
203
|
+
else
|
204
|
+
payload = {
|
205
|
+
'client' => {
|
206
|
+
}
|
207
|
+
}
|
208
|
+
# allow arbitrary -O options
|
209
|
+
payload.deep_merge!({'page' => passed_options}) unless passed_options.empty?
|
210
|
+
# prompt for options
|
211
|
+
#params = Morpheus::Cli::OptionTypes.prompt(update_wiki_page_option_types, options[:options], @api_client, options[:params])
|
212
|
+
params = passed_options
|
213
|
+
|
214
|
+
if params.empty?
|
215
|
+
raise_command_error "Specify at least one option to update.\n#{optparse}"
|
216
|
+
end
|
217
|
+
|
218
|
+
payload.deep_merge!({'client' => params}) unless params.empty?
|
219
|
+
end
|
220
|
+
@clients_interface.setopts(options)
|
221
|
+
if options[:dry_run]
|
222
|
+
print_dry_run @clients_interface.dry.update(client['id'], payload)
|
223
|
+
return
|
224
|
+
end
|
225
|
+
json_response = @clients_interface.update(client['id'], payload)
|
226
|
+
if options[:json]
|
227
|
+
print JSON.pretty_generate(json_response)
|
228
|
+
print "\n"
|
229
|
+
else
|
230
|
+
display_name = json_response['client'] ? json_response['client']['clientId'] : ''
|
231
|
+
print_green_success "Client #{display_name} updated"
|
232
|
+
get([json_response['client']['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
|
233
|
+
end
|
234
|
+
return 0
|
235
|
+
rescue RestClient::Exception => e
|
236
|
+
print_rest_exception(e, options)
|
237
|
+
exit 1
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def remove(args)
|
242
|
+
options = {}
|
243
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
244
|
+
opts.banner = subcommand_usage("[clientId]")
|
245
|
+
build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
|
246
|
+
opts.footer = "Deletes Oauth Client."
|
247
|
+
end
|
248
|
+
optparse.parse!(args)
|
249
|
+
|
250
|
+
if args.count != 1
|
251
|
+
raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args}\n#{optparse}"
|
252
|
+
end
|
253
|
+
|
254
|
+
connect(options)
|
255
|
+
begin
|
256
|
+
client = find_client_by_name_or_id(args[0])
|
257
|
+
return 1 if client.nil?
|
258
|
+
|
259
|
+
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the client #{client['clientId']}?")
|
260
|
+
return 9, "aborted command"
|
261
|
+
end
|
262
|
+
@clients_interface.setopts(options)
|
263
|
+
if options[:dry_run]
|
264
|
+
print_dry_run @clients_interface.dry.destroy(client['id'])
|
265
|
+
return
|
266
|
+
end
|
267
|
+
json_response = @clients_interface.destroy(client['id'])
|
268
|
+
if options[:json]
|
269
|
+
print JSON.pretty_generate(json_response)
|
270
|
+
print "\n"
|
271
|
+
else
|
272
|
+
print_green_success "Client #{client['clientId']} removed"
|
273
|
+
# list([] + (options[:remote] ? ["-r",options[:remote]] : []))
|
274
|
+
end
|
275
|
+
return 0
|
276
|
+
rescue RestClient::Exception => e
|
277
|
+
print_rest_exception(e, options)
|
278
|
+
exit 1
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
|
283
|
+
private
|
284
|
+
def find_client_by_name_or_id(val)
|
285
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
286
|
+
return find_client_by_id(val)
|
287
|
+
else
|
288
|
+
return find_client_by_client_id(val)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
def find_client_by_id(id)
|
293
|
+
raise "#{self.class} has not defined @client_interface" if @clients_interface.nil?
|
294
|
+
begin
|
295
|
+
json_response = @clients_interface.get(id)
|
296
|
+
return json_response['client']
|
297
|
+
rescue RestClient::Exception => e
|
298
|
+
if e.response && e.response.code == 404
|
299
|
+
print_red_alert "Client not found by id #{id}"
|
300
|
+
else
|
301
|
+
raise e
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
def find_client_by_client_id(clientId)
|
307
|
+
raise "#{self.class} has not defined @client_interface" if @clients_interface.nil?
|
308
|
+
clients = @clients_interface.list()['clients'].select { |client| client['clientId'] == clientId }
|
309
|
+
if clients.empty?
|
310
|
+
print_red_alert "Client not found by clientId #{clientId}"
|
311
|
+
return nil
|
312
|
+
elsif clients.size > 1
|
313
|
+
print_red_alert "#{clients.size} Clients found by clientId #{clientId}"
|
314
|
+
print as_pretty_table(clients, [:id,:clientId], {color:red})
|
315
|
+
print reset,"\n"
|
316
|
+
return nil
|
317
|
+
else
|
318
|
+
return clients[0]
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
def client_option_types
|
323
|
+
[
|
324
|
+
{'fieldName' => 'clientId', 'fieldLabel' => 'Client Id', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
|
325
|
+
{'fieldName' => 'accessTokenValiditySeconds', 'fieldLabel' => 'Access Token Validity Length (Seconds)', 'type' => 'number', 'required' => true, 'defaultValue' => 43200,'displayOrder' => 2},
|
326
|
+
{'fieldName' => 'refreshTokenValiditySeconds', 'fieldLabel' => 'Refresh Token Validity Length (Seconds)', 'type' => 'number', 'required' => true, 'defaultValue' => 43200,'displayOrder' => 3}
|
327
|
+
]
|
328
|
+
end
|
329
|
+
|
330
|
+
def add_client_option_types
|
331
|
+
[
|
332
|
+
{'fieldName' => 'clientId', 'fieldLabel' => 'Client Id', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
|
333
|
+
{'fieldName' => 'clientSecret', 'fieldLabel' => 'Client Secret', 'type' => 'text', 'displayOrder' => 2},
|
334
|
+
{'fieldName' => 'accessTokenValiditySeconds', 'fieldLabel' => 'Access Token Validity Length (Seconds)', 'type' => 'number', 'required' => true,'defaultValue' => 43200, 'displayOrder' => 3},
|
335
|
+
{'fieldName' => 'refreshTokenValiditySeconds', 'fieldLabel' => 'Refresh Token Validity Length (Seconds)', 'type' => 'number', 'required' => true,'defaultValue' => 43200, 'displayOrder' => 4}
|
336
|
+
]
|
337
|
+
end
|
338
|
+
end
|