morpheus-cli 4.2.14 → 4.2.19
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/README.md +8 -6
- data/lib/morpheus/api/api_client.rb +32 -14
- data/lib/morpheus/api/auth_interface.rb +4 -2
- data/lib/morpheus/api/backup_jobs_interface.rb +9 -0
- data/lib/morpheus/api/backups_interface.rb +16 -0
- data/lib/morpheus/api/deploy_interface.rb +25 -56
- data/lib/morpheus/api/deployments_interface.rb +44 -55
- data/lib/morpheus/api/doc_interface.rb +57 -0
- data/lib/morpheus/api/instances_interface.rb +5 -0
- data/lib/morpheus/api/rest_interface.rb +40 -0
- data/lib/morpheus/api/user_sources_interface.rb +0 -15
- data/lib/morpheus/api/users_interface.rb +2 -3
- data/lib/morpheus/benchmarking.rb +2 -2
- data/lib/morpheus/cli.rb +4 -1
- data/lib/morpheus/cli/access_token_command.rb +27 -10
- data/lib/morpheus/cli/apps.rb +21 -15
- data/lib/morpheus/cli/backup_jobs_command.rb +276 -0
- data/lib/morpheus/cli/backups_command.rb +271 -0
- data/lib/morpheus/cli/blueprints_command.rb +27 -61
- data/lib/morpheus/cli/boot_scripts_command.rb +1 -1
- data/lib/morpheus/cli/cli_command.rb +183 -45
- data/lib/morpheus/cli/cli_registry.rb +3 -0
- data/lib/morpheus/cli/clouds.rb +7 -10
- data/lib/morpheus/cli/clusters.rb +0 -18
- data/lib/morpheus/cli/commands/standard/benchmark_command.rb +23 -20
- data/lib/morpheus/cli/commands/standard/man_command.rb +1 -1
- data/lib/morpheus/cli/credentials.rb +13 -9
- data/lib/morpheus/cli/deploy.rb +374 -0
- data/lib/morpheus/cli/deployments.rb +521 -197
- data/lib/morpheus/cli/deploys.rb +271 -126
- data/lib/morpheus/cli/doc.rb +182 -0
- data/lib/morpheus/cli/error_handler.rb +23 -8
- data/lib/morpheus/cli/errors.rb +3 -2
- data/lib/morpheus/cli/image_builder_command.rb +2 -2
- data/lib/morpheus/cli/instances.rb +136 -17
- data/lib/morpheus/cli/invoices_command.rb +339 -225
- data/lib/morpheus/cli/jobs_command.rb +2 -2
- data/lib/morpheus/cli/library_layouts_command.rb +1 -1
- data/lib/morpheus/cli/library_option_lists_command.rb +61 -125
- data/lib/morpheus/cli/library_option_types_command.rb +32 -37
- data/lib/morpheus/cli/login.rb +9 -3
- data/lib/morpheus/cli/mixins/accounts_helper.rb +158 -100
- data/lib/morpheus/cli/mixins/backups_helper.rb +115 -0
- data/lib/morpheus/cli/mixins/deployments_helper.rb +135 -0
- data/lib/morpheus/cli/mixins/library_helper.rb +32 -0
- data/lib/morpheus/cli/mixins/option_source_helper.rb +1 -1
- data/lib/morpheus/cli/mixins/print_helper.rb +149 -84
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +2 -2
- data/lib/morpheus/cli/mixins/whoami_helper.rb +19 -6
- data/lib/morpheus/cli/network_routers_command.rb +1 -1
- data/lib/morpheus/cli/option_parser.rb +48 -5
- data/lib/morpheus/cli/option_types.rb +46 -10
- data/lib/morpheus/cli/price_sets_command.rb +1 -1
- data/lib/morpheus/cli/projects_command.rb +7 -7
- data/lib/morpheus/cli/remote.rb +3 -2
- data/lib/morpheus/cli/roles.rb +49 -92
- data/lib/morpheus/cli/security_groups.rb +7 -1
- data/lib/morpheus/cli/service_plans_command.rb +10 -10
- data/lib/morpheus/cli/setup.rb +1 -1
- data/lib/morpheus/cli/shell.rb +7 -6
- data/lib/morpheus/cli/subnets_command.rb +1 -1
- data/lib/morpheus/cli/tasks.rb +24 -10
- data/lib/morpheus/cli/tenants_command.rb +133 -163
- data/lib/morpheus/cli/user_groups_command.rb +20 -65
- data/lib/morpheus/cli/user_settings_command.rb +115 -13
- data/lib/morpheus/cli/user_sources_command.rb +57 -24
- data/lib/morpheus/cli/users.rb +210 -186
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/whitelabel_settings_command.rb +29 -5
- data/lib/morpheus/cli/whoami.rb +113 -6
- data/lib/morpheus/cli/workflows.rb +11 -8
- data/lib/morpheus/ext/hash.rb +21 -0
- data/lib/morpheus/formatters.rb +7 -19
- data/lib/morpheus/terminal.rb +1 -0
- metadata +12 -3
- data/lib/morpheus/cli/auth_command.rb +0 -105
@@ -70,7 +70,7 @@ module Morpheus::Cli::ProvisioningHelper
|
|
70
70
|
|
71
71
|
def get_available_clouds(group_id, refresh=false)
|
72
72
|
if !group_id
|
73
|
-
option_results = options_interface.options_for_source('clouds', {})
|
73
|
+
option_results = options_interface.options_for_source('clouds', {'default' => 'false'})
|
74
74
|
return option_results['data'].collect {|it|
|
75
75
|
{"id" => it["value"], "name" => it["name"], "value" => it["value"], "zoneTypeId" => it["zoneTypeId"]}
|
76
76
|
}
|
@@ -244,7 +244,7 @@ module Morpheus::Cli::ProvisioningHelper
|
|
244
244
|
end
|
245
245
|
|
246
246
|
def find_instance_by_name(name)
|
247
|
-
json_results = instances_interface.
|
247
|
+
json_results = instances_interface.list({name: name.to_s})
|
248
248
|
if json_results['instances'].empty?
|
249
249
|
print_red_alert "Instance not found by name #{name}"
|
250
250
|
exit 1
|
@@ -1,18 +1,31 @@
|
|
1
1
|
require 'morpheus/cli/mixins/print_helper'
|
2
2
|
|
3
3
|
# Mixin for Morpheus::Cli command classes
|
4
|
-
# Provides common methods for fetching and printing
|
5
|
-
# The including class must establish @accounts_interface, @roles_interface, @users_interface
|
4
|
+
# Provides common methods for fetching and printing whoami information
|
6
5
|
module Morpheus::Cli::WhoamiHelper
|
7
6
|
|
8
7
|
def self.included(klass)
|
9
8
|
klass.send :include, Morpheus::Cli::PrintHelper
|
10
9
|
end
|
11
10
|
|
12
|
-
def load_whoami()
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
def load_whoami(refresh=false)
|
12
|
+
appliance = @remote_appliance # from establish_connection()
|
13
|
+
if appliance.nil?
|
14
|
+
print_red_alert "No current appliance. See `remote use`."
|
15
|
+
exit 1
|
16
|
+
end
|
17
|
+
# fetch from cache first
|
18
|
+
whoami_response = nil
|
19
|
+
cached_response = ::Morpheus::Cli::Whoami.load_whoami(appliance[:name], appliance[:username], refresh)
|
20
|
+
if cached_response
|
21
|
+
whoami_response = cached_response
|
22
|
+
else
|
23
|
+
whoami_interface = @whoami_interface || @api_client.whoami
|
24
|
+
whoami_response = whoami_interface.get()
|
25
|
+
# save the result to the cache
|
26
|
+
::Morpheus::Cli::Whoami.save_whoami(appliance[:name], appliance[:username], whoami_response)
|
27
|
+
end
|
28
|
+
|
16
29
|
@current_user = whoami_response["user"]
|
17
30
|
if @current_user.empty?
|
18
31
|
print_red_alert "Unauthenticated. Please login."
|
@@ -1040,7 +1040,7 @@ class Morpheus::Cli::NetworkRoutersCommand
|
|
1040
1040
|
|
1041
1041
|
begin
|
1042
1042
|
if !is_master_account
|
1043
|
-
print_red_alert "Permissions only available for master
|
1043
|
+
print_red_alert "Permissions only available for master tenant"
|
1044
1044
|
return 1
|
1045
1045
|
end
|
1046
1046
|
|
@@ -4,7 +4,11 @@ module Morpheus
|
|
4
4
|
module Cli
|
5
5
|
|
6
6
|
# an enhanced OptionParser
|
7
|
-
#
|
7
|
+
# Modifications include
|
8
|
+
# * footer property to compliment banner with footer="Get details about a thing by ID."
|
9
|
+
# * hidden options with add_hidden_option "--not-in-help"
|
10
|
+
# * errors raised from parse! will have a reference to the parser itself.
|
11
|
+
# this is useful so you can you print the banner (usage) message in your error handling
|
8
12
|
class Morpheus::Cli::OptionParser < OptionParser
|
9
13
|
|
10
14
|
attr_accessor :footer
|
@@ -18,7 +22,7 @@ module Morpheus
|
|
18
22
|
full_help_message
|
19
23
|
end
|
20
24
|
|
21
|
-
def full_help_message
|
25
|
+
def full_help_message(opts={})
|
22
26
|
out = ""
|
23
27
|
#out << original_to_s
|
24
28
|
if banner
|
@@ -40,8 +44,15 @@ module Morpheus
|
|
40
44
|
opt_description.to_s.strip.start_with?("--#{hidden_switch} ")
|
41
45
|
end
|
42
46
|
}
|
43
|
-
if
|
44
|
-
|
47
|
+
if is_hidden
|
48
|
+
if opts[:show_hidden_options]
|
49
|
+
# out << opt_description + " (hidden)"
|
50
|
+
out << opt_description
|
51
|
+
else
|
52
|
+
# hidden
|
53
|
+
end
|
54
|
+
else
|
55
|
+
out << opt_description
|
45
56
|
end
|
46
57
|
end
|
47
58
|
end
|
@@ -66,7 +77,39 @@ module Morpheus
|
|
66
77
|
@hidden_options
|
67
78
|
end
|
68
79
|
|
69
|
-
|
80
|
+
# this needs mods too, but we dont use it...
|
81
|
+
# def parse
|
82
|
+
# end
|
70
83
|
|
84
|
+
def parse!(*args)
|
85
|
+
# it is actually # def parse(argv = default_argv, into: nil)
|
86
|
+
argv = [args].flatten() # args[0].flatten
|
87
|
+
#help_wanted = argv.find {|arg| arg == "--help" || arg == "-h" }
|
88
|
+
help_wanted = (argv.last == "--help" || argv.last == "-h") ? argv.last : nil
|
89
|
+
begin
|
90
|
+
return super(*args)
|
91
|
+
rescue OptionParser::ParseError => e
|
92
|
+
# last arg is --help
|
93
|
+
# maybe they just got the Try --help message and its on the end
|
94
|
+
# so strip all option arguments to avoid OptionParser::InvalidOption, etc.
|
95
|
+
# this is not ideal, it means you cannot pass these strings as the last argument to your command.
|
96
|
+
if help_wanted
|
97
|
+
argv = argv.reject {|arg| arg =~ /^\-+/ }
|
98
|
+
argv << help_wanted
|
99
|
+
return super(argv)
|
100
|
+
else
|
101
|
+
e.optparse = self
|
102
|
+
raise e
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
71
108
|
end
|
72
109
|
end
|
110
|
+
|
111
|
+
# ParseError is overridden to set parser reference.
|
112
|
+
# todo: dont monkey patch like this
|
113
|
+
class OptionParser::ParseError
|
114
|
+
attr_accessor :optparse
|
115
|
+
end
|
@@ -47,7 +47,9 @@ module Morpheus
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
# puts "Options Prompt #{options}"
|
50
|
-
|
50
|
+
# only sort if displayOrder is set
|
51
|
+
sorted_option_types = (option_types[0] && option_types[0]['displayOrder']) ? option_types.sort { |x,y| x['displayOrder'].to_i <=> y['displayOrder'].to_i } : option_types
|
52
|
+
sorted_option_types.each do |option_type|
|
51
53
|
context_map = results
|
52
54
|
value = nil
|
53
55
|
value_found=false
|
@@ -71,17 +73,26 @@ module Morpheus
|
|
71
73
|
|
72
74
|
# respect optionType.dependsOnCode
|
73
75
|
if option_type['dependsOnCode'] && option_type['dependsOnCode'] != ""
|
74
|
-
#
|
76
|
+
# support formats code=value or code:value OR code:(value|value2|value3)
|
75
77
|
parts = option_type['dependsOnCode'].include?("=") ? option_type['dependsOnCode'].split("=") : option_type['dependsOnCode'].split(":")
|
76
78
|
depends_on_code = parts[0]
|
77
|
-
depends_on_value = parts[1]
|
79
|
+
depends_on_value = parts[1].to_s.strip
|
80
|
+
depends_on_values = []
|
81
|
+
if depends_on_value.size > 0
|
82
|
+
# strip parenthesis
|
83
|
+
if depends_on_value[0] && depends_on_value[0].chr == "("
|
84
|
+
depends_on_value = depends_on_value[1..-1]
|
85
|
+
end
|
86
|
+
depends_on_value.chomp(")")
|
87
|
+
depends_on_values = depends_on_value.split("|").collect { |it| it.strip }
|
88
|
+
end
|
78
89
|
depends_on_option_type = option_types.find {|it| it["code"] == depends_on_code }
|
79
90
|
# could not find the dependent option type, proceed and prompt
|
80
91
|
if !depends_on_option_type.nil?
|
81
92
|
# dependent option type has a different value
|
82
93
|
depends_on_field_key = depends_on_option_type['fieldContext'] ? "#{depends_on_option_type['fieldContext']}.#{depends_on_option_type['fieldName']}" : "#{depends_on_option_type['fieldName']}"
|
83
94
|
found_dep_value = get_object_value(results, depends_on_field_key) || get_object_value(options, depends_on_field_key)
|
84
|
-
if
|
95
|
+
if depends_on_values.size > 0 && !depends_on_values.include?(found_dep_value)
|
85
96
|
next
|
86
97
|
end
|
87
98
|
end
|
@@ -311,7 +322,7 @@ module Morpheus
|
|
311
322
|
elsif option_type['optionSource']
|
312
323
|
# calculate from inline lambda
|
313
324
|
if option_type['optionSource'].is_a?(Proc)
|
314
|
-
select_options = option_type['optionSource'].call()
|
325
|
+
select_options = option_type['optionSource'].call(api_client, grails_params(api_params || {}))
|
315
326
|
elsif option_type['optionSource'] == 'list'
|
316
327
|
# /api/options/list is a special action for custom OptionTypeLists, just need to pass the optionTypeId parameter
|
317
328
|
select_options = load_source_options(option_type['optionSource'], api_client, {'optionTypeId' => option_type['id']})
|
@@ -622,14 +633,28 @@ module Morpheus
|
|
622
633
|
if source_type == "local"
|
623
634
|
# prompt for content
|
624
635
|
if file_params['content'].nil?
|
625
|
-
|
636
|
+
if options[:no_prompt]
|
637
|
+
print Term::ANSIColor.red, "\nMissing Required Option\n\n", Term::ANSIColor.reset
|
638
|
+
print Term::ANSIColor.red, " * Content [-O #{full_field_key}.content=] - File Content\n", Term::ANSIColor.reset
|
639
|
+
print "\n"
|
640
|
+
exit 1
|
641
|
+
else
|
642
|
+
file_params['content'] = multiline_prompt({'fieldContext' => full_field_key, 'fieldName' => 'content', 'type' => 'code-editor', 'fieldLabel' => 'Content', 'required' => true})
|
643
|
+
end
|
626
644
|
end
|
627
645
|
elsif source_type == "url"
|
628
646
|
if file_params['url']
|
629
647
|
file_params['contentPath'] = file_params.delete('url')
|
630
648
|
end
|
631
649
|
if file_params['contentPath'].nil?
|
632
|
-
|
650
|
+
if options[:no_prompt]
|
651
|
+
print Term::ANSIColor.red, "\nMissing Required Option\n\n", Term::ANSIColor.reset
|
652
|
+
print Term::ANSIColor.red, " * URL [-O #{full_field_key}.url=] - Path of file in the repository\n", Term::ANSIColor.reset
|
653
|
+
print "\n"
|
654
|
+
exit 1
|
655
|
+
else
|
656
|
+
file_params['contentPath'] = generic_prompt({'fieldContext' => full_field_key, 'fieldName' => 'url', 'fieldLabel' => 'URL', 'type' => 'text', 'required' => true})
|
657
|
+
end
|
633
658
|
end
|
634
659
|
elsif source_type == "repository"
|
635
660
|
if file_params['repository'].nil?
|
@@ -637,10 +662,21 @@ module Morpheus
|
|
637
662
|
file_params['repository'] = {'id' => repository_id}
|
638
663
|
end
|
639
664
|
if file_params['contentPath'].nil?
|
640
|
-
|
665
|
+
if options[:no_prompt]
|
666
|
+
print Term::ANSIColor.red, "\nMissing Required Option\n\n", Term::ANSIColor.reset
|
667
|
+
print Term::ANSIColor.red, " * File Path [-O #{full_field_key}.path=] - Path of file in the repository\n", Term::ANSIColor.reset
|
668
|
+
print "\n"
|
669
|
+
exit 1
|
670
|
+
else
|
671
|
+
file_params['contentPath'] = generic_prompt({'fieldContext' => full_field_key, 'fieldName' => 'path', 'fieldLabel' => 'File Path', 'type' => 'text', 'required' => true})
|
672
|
+
end
|
641
673
|
end
|
642
|
-
if file_params
|
643
|
-
|
674
|
+
if !file_params.key?('contentRef')
|
675
|
+
if options[:no_prompt]
|
676
|
+
# pass
|
677
|
+
else
|
678
|
+
file_params['contentRef'] = generic_prompt({'fieldContext' => full_field_key, 'fieldName' => 'ref', 'fieldLabel' => 'Version Ref', 'type' => 'text'})
|
679
|
+
end
|
644
680
|
end
|
645
681
|
end
|
646
682
|
return file_params
|
@@ -461,7 +461,7 @@ class Morpheus::Cli::PriceSetsCommand
|
|
461
461
|
private
|
462
462
|
|
463
463
|
def currency_sym(currency)
|
464
|
-
Money::Currency.new((currency
|
464
|
+
Money::Currency.new((currency.to_s != '' ? currency : 'usd').to_sym).symbol
|
465
465
|
end
|
466
466
|
|
467
467
|
def price_prefix(price)
|
@@ -102,7 +102,7 @@ EOT
|
|
102
102
|
options = {}
|
103
103
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
104
104
|
opts.banner = subcommand_usage("[project]")
|
105
|
-
|
105
|
+
build_standard_get_options(opts, options, [:find_by_name])
|
106
106
|
opts.footer = <<-EOT
|
107
107
|
Get details about a project.
|
108
108
|
[project] is required. This is the name or id of a project.
|
@@ -127,8 +127,8 @@ EOT
|
|
127
127
|
end
|
128
128
|
return
|
129
129
|
end
|
130
|
-
project = find_project_by_name_or_id(id)
|
131
|
-
|
130
|
+
project = options[:find_by_name] ? find_project_by_name(id) : find_project_by_name_or_id(id)
|
131
|
+
return 1, "project not found by '#{id}'" if project.nil?
|
132
132
|
# refetch it by id
|
133
133
|
json_response = {'project' => project}
|
134
134
|
unless id.to_s =~ /\A\d{1,}\Z/
|
@@ -332,7 +332,7 @@ EOT
|
|
332
332
|
opts.on('--remove-resources LIST', Array, "Remove Resources, comma separated list of resource names or IDs to remove.") do |list|
|
333
333
|
remove_resource_ids = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
334
334
|
end
|
335
|
-
build_standard_update_options(opts, options)
|
335
|
+
build_standard_update_options(opts, options, [:find_by_name])
|
336
336
|
opts.footer = <<-EOT
|
337
337
|
Update a project.
|
338
338
|
[project] is required. This is the name or id of a project.
|
@@ -342,7 +342,7 @@ EOT
|
|
342
342
|
verify_args!(args:args, optparse:optparse, count:1)
|
343
343
|
connect(options)
|
344
344
|
exit_code, err = 0, nil
|
345
|
-
project = find_project_by_name_or_id(args[0])
|
345
|
+
project = options[:find_by_name] ? find_project_by_name(args[0]) : find_project_by_name_or_id(args[0])
|
346
346
|
return 1, "project not found by '#{args[0]}'" if project.nil?
|
347
347
|
# construct payload
|
348
348
|
if options[:payload]
|
@@ -433,7 +433,7 @@ EOT
|
|
433
433
|
options = {}
|
434
434
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
435
435
|
opts.banner = subcommand_usage("[project]")
|
436
|
-
|
436
|
+
build_standard_remove_options(opts, options, [:find_by_name])
|
437
437
|
# opts.on( '-f', '--force', "Force Delete" ) do
|
438
438
|
# params[:force] = true
|
439
439
|
# end
|
@@ -446,7 +446,7 @@ EOT
|
|
446
446
|
verify_args!(args:args, optparse:optparse, count:1)
|
447
447
|
connect(options)
|
448
448
|
exit_code, err = 0, nil
|
449
|
-
project = find_project_by_name_or_id(args[0])
|
449
|
+
project = options[:find_by_name] ? find_project_by_name(args[0]) : find_project_by_name_or_id(args[0])
|
450
450
|
return 1, "project not found by '#{args[0]}'" if project.nil?
|
451
451
|
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the project #{project['name']}?")
|
452
452
|
return 9, "aborted command"
|
data/lib/morpheus/cli/remote.rb
CHANGED
@@ -44,7 +44,7 @@ class Morpheus::Cli::Remote
|
|
44
44
|
current_only = false
|
45
45
|
do_check = false
|
46
46
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
47
|
-
opts.banner = subcommand_usage()
|
47
|
+
opts.banner = subcommand_usage("[search]")
|
48
48
|
opts.on("-a",'--all', "Show all the appliance activity details") do
|
49
49
|
show_all_activity = true
|
50
50
|
options[:wrap] = true
|
@@ -61,8 +61,9 @@ List the configured remote appliances.
|
|
61
61
|
EOT
|
62
62
|
end
|
63
63
|
optparse.parse!(args)
|
64
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
64
65
|
if args.count > 0
|
65
|
-
|
66
|
+
options[:phrase] = args.join(" ")
|
66
67
|
end
|
67
68
|
#connect(options)
|
68
69
|
params.merge!(parse_list_options(options))
|
data/lib/morpheus/cli/roles.rb
CHANGED
@@ -12,6 +12,7 @@ class Morpheus::Cli::Roles
|
|
12
12
|
include Morpheus::Cli::CliCommand
|
13
13
|
include Morpheus::Cli::AccountsHelper
|
14
14
|
include Morpheus::Cli::ProvisioningHelper
|
15
|
+
include Morpheus::Cli::WhoamiHelper
|
15
16
|
register_subcommands :list, :get, :add, :update, :remove, :'list-permissions', :'update-feature-access', :'update-global-group-access', :'update-group-access', :'update-global-cloud-access', :'update-cloud-access', :'update-global-instance-type-access', :'update-instance-type-access', :'update-global-blueprint-access', :'update-blueprint-access'
|
16
17
|
alias_subcommand :details, :get
|
17
18
|
set_default_subcommand :list
|
@@ -37,36 +38,28 @@ class Morpheus::Cli::Roles
|
|
37
38
|
def list(args)
|
38
39
|
options = {}
|
39
40
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
40
|
-
opts.banner = subcommand_usage()
|
41
|
-
|
41
|
+
opts.banner = subcommand_usage("[search phrase]")
|
42
|
+
build_standard_list_options(opts, options)
|
42
43
|
opts.footer = "List roles."
|
43
44
|
end
|
44
45
|
optparse.parse!(args)
|
45
|
-
|
46
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
47
|
+
options[:phrase] = args.join(" ") if args.count > 0
|
46
48
|
connect(options)
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
puts as_json(json_response, options, "roles")
|
62
|
-
return 0
|
63
|
-
elsif options[:yaml]
|
64
|
-
puts as_yaml(json_response, options, "roles")
|
65
|
-
return 0
|
66
|
-
elsif options[:csv]
|
67
|
-
puts records_as_csv(json_response['roles'], options)
|
68
|
-
return 0
|
69
|
-
end
|
49
|
+
|
50
|
+
account = find_account_from_options(options)
|
51
|
+
account_id = account ? account['id'] : nil
|
52
|
+
params = {}
|
53
|
+
params.merge!(parse_list_options(options))
|
54
|
+
@roles_interface.setopts(options)
|
55
|
+
if options[:dry_run]
|
56
|
+
print_dry_run @roles_interface.dry.list(account_id, params), options
|
57
|
+
return 0, nil
|
58
|
+
end
|
59
|
+
load_whoami()
|
60
|
+
json_response = @roles_interface.list(account_id, params)
|
61
|
+
|
62
|
+
render_response(json_response, options, "roles") do
|
70
63
|
roles = json_response['roles']
|
71
64
|
title = "Morpheus Roles"
|
72
65
|
subtitles = []
|
@@ -75,22 +68,20 @@ class Morpheus::Cli::Roles
|
|
75
68
|
if roles.empty?
|
76
69
|
print cyan,"No roles found.",reset,"\n"
|
77
70
|
else
|
78
|
-
|
71
|
+
print cyan
|
72
|
+
columns = @is_master_account ? role_column_definitions : subtenant_role_column_definitions
|
73
|
+
print as_pretty_table(roles, columns.upcase_keys!, options)
|
79
74
|
print_results_pagination(json_response)
|
80
75
|
end
|
81
76
|
print reset,"\n"
|
82
|
-
return 0
|
83
|
-
rescue RestClient::Exception => e
|
84
|
-
print_rest_exception(e, options)
|
85
|
-
exit 1
|
86
77
|
end
|
78
|
+
return 0, nil
|
87
79
|
end
|
88
80
|
|
89
81
|
def get(args)
|
90
82
|
options = {}
|
91
|
-
params = {}
|
92
83
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
93
|
-
opts.banner = subcommand_usage("[
|
84
|
+
opts.banner = subcommand_usage("[role]")
|
94
85
|
opts.on('-p','--permissions', "Display Permissions") do |val|
|
95
86
|
options[:include_feature_access] = true
|
96
87
|
end
|
@@ -117,19 +108,26 @@ class Morpheus::Cli::Roles
|
|
117
108
|
options[:include_instance_type_access] = true
|
118
109
|
options[:include_blueprint_access] = true
|
119
110
|
end
|
120
|
-
|
121
|
-
opts.footer =
|
122
|
-
|
111
|
+
build_standard_get_options(opts, options)
|
112
|
+
opts.footer = <<-EOT
|
113
|
+
Get details about a role.
|
114
|
+
[role] is required. This is the name (authority) or id of a role.
|
115
|
+
EOT
|
123
116
|
end
|
124
117
|
optparse.parse!(args)
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
118
|
+
verify_args!(args:args, optparse:optparse, min:1)
|
119
|
+
connect(options)
|
120
|
+
id_list = parse_id_list(args)
|
121
|
+
return run_command_for_each_arg(id_list) do |arg|
|
122
|
+
_get(arg, options)
|
129
123
|
end
|
124
|
+
end
|
130
125
|
|
131
|
-
|
132
|
-
|
126
|
+
def _get(id, options={})
|
127
|
+
args = [id] # heh
|
128
|
+
params = {}
|
129
|
+
|
130
|
+
|
133
131
|
account = find_account_from_options(options)
|
134
132
|
account_id = account ? account['id'] : nil
|
135
133
|
|
@@ -150,7 +148,7 @@ class Morpheus::Cli::Roles
|
|
150
148
|
# refetch from show action, argh
|
151
149
|
# json_response = @roles_interface.get(account_id, role['id'])
|
152
150
|
# role = json_response['role']
|
153
|
-
|
151
|
+
load_whoami()
|
154
152
|
json_response = nil
|
155
153
|
if args[0].to_s =~ /\A\d{1,}\Z/
|
156
154
|
json_response = @roles_interface.get(account_id, args[0].to_i)
|
@@ -163,27 +161,13 @@ class Morpheus::Cli::Roles
|
|
163
161
|
role = json_response['role']
|
164
162
|
end
|
165
163
|
|
166
|
-
|
167
|
-
|
168
|
-
|
164
|
+
render_response(json_response, options, 'role') do
|
165
|
+
|
169
166
|
print cyan
|
170
167
|
print_h1 "Role Details", options
|
171
168
|
print cyan
|
172
|
-
|
173
|
-
|
174
|
-
"Name" => 'authority',
|
175
|
-
"Description" => 'description',
|
176
|
-
"Scope" => lambda {|it| it['scope'] },
|
177
|
-
"Type" => lambda {|it| format_role_type(it) },
|
178
|
-
"Multitenant" => lambda {|it|
|
179
|
-
format_boolean(it['multitenant']).to_s + (it['multitenantLocked'] ? " (LOCKED)" : "")
|
180
|
-
},
|
181
|
-
"Owner" => lambda {|it| role['owner'] ? role['owner']['name'] : '' },
|
182
|
-
#"Account" => lambda {|it| it['account'] ? it['account']['name'] : '' },
|
183
|
-
"Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
184
|
-
"Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
|
185
|
-
}
|
186
|
-
print_description_list(description_cols, role)
|
169
|
+
columns = @is_master_account ? role_column_definitions : subtenant_role_column_definitions
|
170
|
+
print_description_list(columns, role, options)
|
187
171
|
|
188
172
|
# print_h2 "Role Instance Limits", options
|
189
173
|
# print cyan
|
@@ -310,13 +294,9 @@ class Morpheus::Cli::Roles
|
|
310
294
|
# print "\n"
|
311
295
|
# print cyan,bold,"Blueprint Access: #{get_access_string(json_response['globalAppTemplateAccess'])}",reset,"\n"
|
312
296
|
end
|
313
|
-
|
314
297
|
print reset,"\n"
|
315
|
-
return 0
|
316
|
-
rescue RestClient::Exception => e
|
317
|
-
print_rest_exception(e, options)
|
318
|
-
exit 1
|
319
298
|
end
|
299
|
+
return 0, nil
|
320
300
|
end
|
321
301
|
|
322
302
|
def list_permissions(args)
|
@@ -328,14 +308,9 @@ class Morpheus::Cli::Roles
|
|
328
308
|
"[role] is required. This is the name or id of a role."
|
329
309
|
end
|
330
310
|
optparse.parse!(args)
|
331
|
-
|
332
|
-
if args.count < 1
|
333
|
-
puts optparse
|
334
|
-
return 1
|
335
|
-
end
|
336
|
-
|
311
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
337
312
|
connect(options)
|
338
|
-
|
313
|
+
|
339
314
|
account = find_account_from_options(options)
|
340
315
|
account_id = account ? account['id'] : nil
|
341
316
|
|
@@ -406,14 +381,10 @@ class Morpheus::Cli::Roles
|
|
406
381
|
|
407
382
|
print reset,"\n"
|
408
383
|
return 0
|
409
|
-
|
410
|
-
print_rest_exception(e, options)
|
411
|
-
exit 1
|
412
|
-
end
|
384
|
+
|
413
385
|
end
|
414
386
|
|
415
387
|
def add(args)
|
416
|
-
usage = "Usage: morpheus roles add [options]"
|
417
388
|
options = {}
|
418
389
|
params = {}
|
419
390
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
@@ -519,7 +490,6 @@ class Morpheus::Cli::Roles
|
|
519
490
|
end
|
520
491
|
|
521
492
|
def update(args)
|
522
|
-
usage = "Usage: morpheus roles update [name] [options]"
|
523
493
|
options = {}
|
524
494
|
params = {}
|
525
495
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
@@ -599,7 +569,6 @@ class Morpheus::Cli::Roles
|
|
599
569
|
end
|
600
570
|
|
601
571
|
def remove(args)
|
602
|
-
usage = "Usage: morpheus roles remove [name]"
|
603
572
|
options = {}
|
604
573
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
605
574
|
opts.banner = subcommand_usage("[name]")
|
@@ -1311,7 +1280,6 @@ class Morpheus::Cli::Roles
|
|
1311
1280
|
]
|
1312
1281
|
end
|
1313
1282
|
|
1314
|
-
"A Multitenant role is automatically copied into all existing subaccounts as well as placed into a subaccount when created. Useful for providing a set of predefined roles a Customer can use"
|
1315
1283
|
def update_role_option_types
|
1316
1284
|
add_role_option_types.reject {|it| ['roleType', 'baseRole'].include?(it['fieldName']) }
|
1317
1285
|
end
|
@@ -1328,17 +1296,6 @@ class Morpheus::Cli::Roles
|
|
1328
1296
|
end
|
1329
1297
|
end
|
1330
1298
|
|
1331
|
-
|
1332
|
-
def load_whoami
|
1333
|
-
whoami_response = @whoami_interface.get()
|
1334
|
-
@current_user = whoami_response["user"]
|
1335
|
-
if @current_user.empty?
|
1336
|
-
print_red_alert "Unauthenticated. Please login."
|
1337
|
-
exit 1
|
1338
|
-
end
|
1339
|
-
@is_master_account = whoami_response["isMasterAccount"]
|
1340
|
-
end
|
1341
|
-
|
1342
1299
|
def role_type_options
|
1343
1300
|
[{'name' => 'User Role', 'value' => 'user'}, {'name' => 'Account Role', 'value' => 'account'}]
|
1344
1301
|
end
|