morpheus-cli 4.2.14 → 4.2.19
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/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
|