morpheus-cli 4.1.8 → 4.1.9
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 +24 -0
- data/lib/morpheus/api/{old_cypher_interface.rb → budgets_interface.rb} +10 -11
- data/lib/morpheus/api/cloud_datastores_interface.rb +7 -0
- data/lib/morpheus/api/cloud_resource_pools_interface.rb +2 -2
- data/lib/morpheus/api/cypher_interface.rb +18 -12
- data/lib/morpheus/api/health_interface.rb +72 -0
- data/lib/morpheus/api/instances_interface.rb +1 -1
- data/lib/morpheus/api/library_instance_types_interface.rb +7 -0
- data/lib/morpheus/api/log_settings_interface.rb +6 -0
- data/lib/morpheus/api/network_security_servers_interface.rb +30 -0
- data/lib/morpheus/api/price_sets_interface.rb +42 -0
- data/lib/morpheus/api/prices_interface.rb +68 -0
- data/lib/morpheus/api/provisioning_settings_interface.rb +29 -0
- data/lib/morpheus/api/servers_interface.rb +1 -1
- data/lib/morpheus/api/service_plans_interface.rb +34 -11
- data/lib/morpheus/api/task_sets_interface.rb +8 -0
- data/lib/morpheus/api/tasks_interface.rb +8 -0
- data/lib/morpheus/cli.rb +6 -3
- data/lib/morpheus/cli/appliance_settings_command.rb +13 -5
- data/lib/morpheus/cli/approvals_command.rb +1 -1
- data/lib/morpheus/cli/apps.rb +88 -28
- data/lib/morpheus/cli/backup_settings_command.rb +1 -1
- data/lib/morpheus/cli/blueprints_command.rb +2 -0
- data/lib/morpheus/cli/budgets_command.rb +672 -0
- data/lib/morpheus/cli/cli_command.rb +13 -2
- data/lib/morpheus/cli/cli_registry.rb +1 -0
- data/lib/morpheus/cli/clusters.rb +40 -274
- data/lib/morpheus/cli/commands/standard/benchmark_command.rb +114 -66
- data/lib/morpheus/cli/commands/standard/coloring_command.rb +12 -0
- data/lib/morpheus/cli/commands/standard/curl_command.rb +31 -6
- data/lib/morpheus/cli/commands/standard/echo_command.rb +8 -3
- data/lib/morpheus/cli/commands/standard/set_prompt_command.rb +1 -1
- data/lib/morpheus/cli/containers_command.rb +37 -24
- data/lib/morpheus/cli/cypher_command.rb +191 -150
- data/lib/morpheus/cli/health_command.rb +903 -0
- data/lib/morpheus/cli/hosts.rb +43 -32
- data/lib/morpheus/cli/instances.rb +119 -68
- data/lib/morpheus/cli/jobs_command.rb +1 -1
- data/lib/morpheus/cli/library_instance_types_command.rb +61 -11
- data/lib/morpheus/cli/library_option_types_command.rb +2 -2
- data/lib/morpheus/cli/log_settings_command.rb +46 -3
- data/lib/morpheus/cli/logs_command.rb +24 -17
- data/lib/morpheus/cli/mixins/accounts_helper.rb +2 -0
- data/lib/morpheus/cli/mixins/logs_helper.rb +73 -19
- data/lib/morpheus/cli/mixins/print_helper.rb +29 -1
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +554 -96
- data/lib/morpheus/cli/mixins/whoami_helper.rb +13 -1
- data/lib/morpheus/cli/networks_command.rb +3 -0
- data/lib/morpheus/cli/option_types.rb +83 -53
- data/lib/morpheus/cli/price_sets_command.rb +543 -0
- data/lib/morpheus/cli/prices_command.rb +669 -0
- data/lib/morpheus/cli/processes_command.rb +0 -2
- data/lib/morpheus/cli/provisioning_settings_command.rb +237 -0
- data/lib/morpheus/cli/remote.rb +9 -4
- data/lib/morpheus/cli/reports_command.rb +10 -4
- data/lib/morpheus/cli/roles.rb +93 -38
- data/lib/morpheus/cli/security_groups.rb +10 -0
- data/lib/morpheus/cli/service_plans_command.rb +736 -0
- data/lib/morpheus/cli/tasks.rb +220 -8
- data/lib/morpheus/cli/tenants_command.rb +3 -16
- data/lib/morpheus/cli/users.rb +2 -25
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/whitelabel_settings_command.rb +18 -18
- data/lib/morpheus/cli/whoami.rb +28 -10
- data/lib/morpheus/cli/workflows.rb +488 -36
- data/lib/morpheus/formatters.rb +22 -0
- data/morpheus-cli.gemspec +1 -0
- metadata +28 -5
- data/lib/morpheus/cli/accounts.rb +0 -335
- data/lib/morpheus/cli/old_cypher_command.rb +0 -412
@@ -120,8 +120,8 @@ class Morpheus::Cli::LibraryOptionTypesCommand
|
|
120
120
|
return
|
121
121
|
end
|
122
122
|
option_type = find_option_type_by_name_or_id(id)
|
123
|
-
|
124
|
-
|
123
|
+
return 1 if option_type.nil?
|
124
|
+
json_response = {'optionType' => option_type}
|
125
125
|
if options[:json]
|
126
126
|
puts as_json(json_response, options, "optionType")
|
127
127
|
return 0
|
@@ -5,9 +5,9 @@ class Morpheus::Cli::LogSettingsCommand
|
|
5
5
|
include Morpheus::Cli::AccountsHelper
|
6
6
|
|
7
7
|
set_command_name :'log-settings'
|
8
|
-
|
8
|
+
|
9
9
|
register_subcommands :get, :update
|
10
|
-
register_subcommands :enable_integration, :disable_integration
|
10
|
+
register_subcommands :enable_integration, :disable_integration, :remove_integration
|
11
11
|
register_subcommands :add_syslog_rule, :remove_syslog_rule
|
12
12
|
|
13
13
|
set_default_subcommand :get
|
@@ -92,7 +92,7 @@ class Morpheus::Cli::LogSettingsCommand
|
|
92
92
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
93
93
|
opts.banner = opts.banner = subcommand_usage()
|
94
94
|
opts.on("--enabled [on|off]", ['on','off'], "Logs enabled") do |val|
|
95
|
-
params['enabled'] =
|
95
|
+
params['enabled'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
|
96
96
|
end
|
97
97
|
opts.on("-R", "--retention NUMBER", Integer, "Availability time frame in days") do |val|
|
98
98
|
params['retentionDays'] = val.to_i
|
@@ -284,6 +284,49 @@ class Morpheus::Cli::LogSettingsCommand
|
|
284
284
|
end
|
285
285
|
end
|
286
286
|
|
287
|
+
def remove_integration(args)
|
288
|
+
options = {}
|
289
|
+
|
290
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
291
|
+
opts.banner = opts.banner = subcommand_usage("[name]")
|
292
|
+
build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
|
293
|
+
opts.footer = "Deletes specifed integration.\n" +
|
294
|
+
"[name] is required. Currently supports splunk and logrhythm integrations."
|
295
|
+
end
|
296
|
+
|
297
|
+
optparse.parse!(args)
|
298
|
+
connect(options)
|
299
|
+
if args.count != 1
|
300
|
+
raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args}\n#{optparse}"
|
301
|
+
return 1
|
302
|
+
end
|
303
|
+
|
304
|
+
begin
|
305
|
+
@log_settings_interface.setopts(options)
|
306
|
+
if options[:dry_run]
|
307
|
+
print_dry_run @log_settings_interface.dry.destroy_integration(args[0])
|
308
|
+
return
|
309
|
+
end
|
310
|
+
json_response = @log_settings_interface.destroy_integration(args[0])
|
311
|
+
|
312
|
+
if options[:json]
|
313
|
+
puts as_json(json_response, options)
|
314
|
+
elsif !options[:quiet]
|
315
|
+
if json_response['success']
|
316
|
+
print_green_success "Integration removed"
|
317
|
+
get([] + (options[:remote] ? ["-r",options[:remote]] : []))
|
318
|
+
else
|
319
|
+
print_red_alert "Error removing integration: #{json_response['msg'] || json_response['errors']}"
|
320
|
+
end
|
321
|
+
end
|
322
|
+
return 0
|
323
|
+
|
324
|
+
rescue RestClient::Exception => e
|
325
|
+
print_rest_exception(e, options)
|
326
|
+
exit 1
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
287
330
|
def add_syslog_rule(args)
|
288
331
|
options = {}
|
289
332
|
|
@@ -62,6 +62,15 @@ class Morpheus::Cli::LogsCommand
|
|
62
62
|
# opts.on('--interval TIME','--interval TIME', "Interval of time to include, in seconds. Default is 30 days ago.") do |val|
|
63
63
|
# options[:interval] = parse_time(val).utc.iso8601
|
64
64
|
# end
|
65
|
+
opts.on('--level VALUE', String, "Log Level. DEBUG,INFO,WARN,ERROR") do |val|
|
66
|
+
params['level'] = params['level'] ? [params['level'], val].flatten : val
|
67
|
+
end
|
68
|
+
opts.on('--table', '--table', "Format ouput as a table.") do
|
69
|
+
options[:table] = true
|
70
|
+
end
|
71
|
+
opts.on('-a', '--all', "Display all details: entire message." ) do
|
72
|
+
options[:details] = true
|
73
|
+
end
|
65
74
|
build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
66
75
|
opts.footer = "List logs for a container.\n" +
|
67
76
|
"[id] is required. This is the id of a container."
|
@@ -73,7 +82,7 @@ class Morpheus::Cli::LogsCommand
|
|
73
82
|
connect(options)
|
74
83
|
begin
|
75
84
|
params.merge!(parse_list_options(options))
|
76
|
-
params[
|
85
|
+
params['query'] = params.delete('phrase') if params['phrase']
|
77
86
|
params['order'] = params['direction'] unless params['direction'].nil? # old api version expects order instead of direction
|
78
87
|
params['startMs'] = (options[:start].to_i * 1000) if options[:start]
|
79
88
|
params['endMs'] = (options[:end].to_i * 1000) if options[:end]
|
@@ -85,22 +94,19 @@ class Morpheus::Cli::LogsCommand
|
|
85
94
|
return
|
86
95
|
end
|
87
96
|
json_response = @logs_interface.list(params)
|
88
|
-
render_result = render_with_format(json_response, options, 'data')
|
97
|
+
render_result = json_response['logs'] ? render_with_format(json_response, options, 'logs') : render_with_format(json_response, options, 'data')
|
89
98
|
return 0 if render_result
|
90
99
|
|
91
100
|
title = "Morpheus Logs"
|
92
101
|
subtitles = parse_list_subtitles(options)
|
93
|
-
if
|
94
|
-
subtitles << "Start: #{
|
95
|
-
end
|
96
|
-
if params[:end]
|
97
|
-
subtitles << "End: #{params[:end]}".strip
|
102
|
+
if options[:start]
|
103
|
+
subtitles << "Start: #{options[:start]}".strip
|
98
104
|
end
|
99
|
-
if
|
100
|
-
subtitles << "
|
105
|
+
if options[:end]
|
106
|
+
subtitles << "End: #{options[:end]}".strip
|
101
107
|
end
|
102
|
-
if params[
|
103
|
-
subtitles << "Search: #{params[
|
108
|
+
if params['query']
|
109
|
+
subtitles << "Search: #{params['query']}".strip
|
104
110
|
end
|
105
111
|
if params['servers']
|
106
112
|
subtitles << "Servers: #{params['servers']}".strip
|
@@ -111,15 +117,16 @@ class Morpheus::Cli::LogsCommand
|
|
111
117
|
if params['clusters']
|
112
118
|
subtitles << "Clusters: #{params['clusters']}".strip
|
113
119
|
end
|
114
|
-
if params[
|
115
|
-
subtitles << "
|
120
|
+
if params['level']
|
121
|
+
subtitles << "Level: #{params['level']}"
|
116
122
|
end
|
117
123
|
print_h1 title, subtitles, options
|
118
|
-
|
119
|
-
|
124
|
+
logs = json_response['data'] || json_response['logs']
|
125
|
+
if logs.empty?
|
126
|
+
print "#{cyan}No logs found.#{reset}\n"
|
120
127
|
else
|
121
|
-
|
122
|
-
print_results_pagination({'meta'=>{'total'=>json_response['total']
|
128
|
+
print format_log_records(logs, options)
|
129
|
+
print_results_pagination({'meta'=>{'total'=>(json_response['total']['value'] rescue json_response['total']),'size'=>logs.size,'max'=>(json_response['max'] || options[:max]),'offset'=>(json_response['offset'] || options[:offset] || 0)}})
|
123
130
|
end
|
124
131
|
print reset,"\n"
|
125
132
|
return 0
|
@@ -331,6 +331,8 @@ module Morpheus::Cli::AccountsHelper
|
|
331
331
|
val ||= 'none'
|
332
332
|
if val == 'none'
|
333
333
|
"#{white}#{val.to_s.capitalize}#{cyan}"
|
334
|
+
# elsif val == 'read'
|
335
|
+
# "#{cyan}#{val.to_s.capitalize}#{cyan}"
|
334
336
|
else
|
335
337
|
"#{green}#{val.to_s.capitalize}#{cyan}"
|
336
338
|
end
|
@@ -15,6 +15,12 @@ module Morpheus::Cli::LogsHelper
|
|
15
15
|
@logs_interface
|
16
16
|
end
|
17
17
|
|
18
|
+
def instances_interface
|
19
|
+
# @api_client.instances
|
20
|
+
raise "#{self.class} has not defined @instances_interface" if @instances_interface.nil?
|
21
|
+
@instances_interface
|
22
|
+
end
|
23
|
+
|
18
24
|
def containers_interface
|
19
25
|
## @api_client.containers
|
20
26
|
raise "#{self.class} has not defined @logs_interface" if @containers_interface.nil?
|
@@ -33,33 +39,81 @@ module Morpheus::Cli::LogsHelper
|
|
33
39
|
@clusters_interface
|
34
40
|
end
|
35
41
|
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
def format_log_records(log_records, options={})
|
42
|
+
def format_log_records(log_records, options={}, show_object=true)
|
43
|
+
if options[:table]
|
44
|
+
return format_log_table(log_records, options, show_object)
|
45
|
+
end
|
41
46
|
out = ""
|
42
47
|
table_color = options.key?(:color) ? options[:color] : cyan
|
43
48
|
log_records.each do |log_entry|
|
44
|
-
log_level = ''
|
45
|
-
case log_entry['level']
|
46
|
-
when 'INFO'
|
47
|
-
log_level = "#{blue}#{bold}INFO#{reset}"
|
48
|
-
when 'DEBUG'
|
49
|
-
log_level = "#{white}#{bold}DEBUG#{reset}"
|
50
|
-
when 'WARN'
|
51
|
-
log_level = "#{yellow}#{bold}WARN#{reset}"
|
52
|
-
when 'ERROR'
|
53
|
-
log_level = "#{red}#{bold}ERROR#{reset}"
|
54
|
-
when 'FATAL'
|
55
|
-
log_level = "#{red}#{bold}FATAL#{reset}"
|
56
|
-
end
|
49
|
+
log_level = format_log_level(log_entry['level'], table_color, 6)
|
57
50
|
out << table_color if table_color
|
58
|
-
out << "[#{log_entry['ts']}] #{log_level} - #{log_entry['message'].to_s.strip}"
|
51
|
+
# out << "[#{log_entry['ts']}] #{log_level} - #{log_entry['message'].to_s.strip}"
|
52
|
+
out << "#{log_level} "
|
53
|
+
out << "[#{log_entry['ts']}] "
|
54
|
+
if show_object
|
55
|
+
out << "(#{log_entry['typeCode']} #{log_entry['objectId']}) "
|
56
|
+
end
|
57
|
+
log_msg = ""
|
58
|
+
if options[:details] || options[:all]
|
59
|
+
log_msg = log_entry['message'].to_s.strip
|
60
|
+
else
|
61
|
+
# truncate_string(log_entry['message'].to_s.split.select {|it| it.to_s.strip != "" }.first, 100)
|
62
|
+
log_msg = truncate_string(log_entry['message'].to_s.gsub("\r\n", " ").gsub("\n", " "), 100)
|
63
|
+
end
|
64
|
+
out << "- #{log_msg}"
|
59
65
|
out << table_color if table_color
|
60
66
|
out << "\n"
|
61
67
|
end
|
62
68
|
return out
|
63
69
|
end
|
64
70
|
|
71
|
+
def format_log_table(logs, options={}, show_object=true)
|
72
|
+
out = ""
|
73
|
+
table_color = options.key?(:color) ? options[:color] : cyan
|
74
|
+
log_columns = [
|
75
|
+
{"LEVEL" => lambda {|log_entry| format_log_level(log_entry['level'], table_color) } },
|
76
|
+
{"DATE" => lambda {|log_entry| log_entry['ts'] } },
|
77
|
+
{"SOURCE" => lambda {|log_entry| "#{log_entry['typeCode']} #{log_entry['objectId']}" } },
|
78
|
+
{"MESSAGE" => lambda {|log_entry|
|
79
|
+
if options[:details] || options[:all]
|
80
|
+
log_entry['message'].to_s
|
81
|
+
else
|
82
|
+
truncate_string(log_entry['message'].to_s.split.first, 100)
|
83
|
+
end
|
84
|
+
} }
|
85
|
+
]
|
86
|
+
if show_object != true
|
87
|
+
log_columns = log_columns.reject {|it| it.key?("SOURCE") }
|
88
|
+
end
|
89
|
+
# if options[:include_fields]
|
90
|
+
# columns = options[:include_fields]
|
91
|
+
# end
|
92
|
+
out << as_pretty_table(logs, log_columns, options.merge(responsive_table:false))
|
93
|
+
# out << "\n"
|
94
|
+
return out
|
95
|
+
end
|
96
|
+
|
97
|
+
def format_log_level(val, return_color=cyan, label_width=nil)
|
98
|
+
log_level = ''
|
99
|
+
display_value = val.to_s
|
100
|
+
if label_width
|
101
|
+
display_value = display_value.ljust(label_width, ' ')
|
102
|
+
end
|
103
|
+
case val
|
104
|
+
when 'INFO'
|
105
|
+
log_level = "#{blue}#{bold}#{display_value}#{reset}#{return_color}"
|
106
|
+
when 'DEBUG'
|
107
|
+
log_level = "#{white}#{bold}#{display_value}#{reset}#{return_color}"
|
108
|
+
when 'WARN'
|
109
|
+
log_level = "#{yellow}#{bold}#{display_value}#{reset}#{return_color}"
|
110
|
+
when 'ERROR'
|
111
|
+
log_level = "#{red}#{bold}#{display_value}#{reset}#{return_color}"
|
112
|
+
when 'FATAL'
|
113
|
+
log_level = "#{red}#{bold}#{display_value}#{reset}#{return_color}"
|
114
|
+
else
|
115
|
+
log_level = val
|
116
|
+
end
|
117
|
+
return log_level
|
118
|
+
end
|
65
119
|
end
|
@@ -1026,7 +1026,8 @@ module Morpheus::Cli::PrintHelper
|
|
1026
1026
|
|
1027
1027
|
if options[:include_fields]
|
1028
1028
|
if object_key
|
1029
|
-
data[object_key] = filter_data(data[object_key], options[:include_fields])
|
1029
|
+
# data[object_key] = filter_data(data[object_key], options[:include_fields])
|
1030
|
+
data = {(object_key) => filter_data(data[object_key], options[:include_fields]) }
|
1030
1031
|
else
|
1031
1032
|
data = filter_data(data, options[:include_fields])
|
1032
1033
|
end
|
@@ -1115,4 +1116,31 @@ module Morpheus::Cli::PrintHelper
|
|
1115
1116
|
end
|
1116
1117
|
end
|
1117
1118
|
|
1119
|
+
def format_percent(val, sig_dig=2)
|
1120
|
+
if val.nil?
|
1121
|
+
return ""
|
1122
|
+
end
|
1123
|
+
percent_value = val.to_f
|
1124
|
+
if percent_value == 0
|
1125
|
+
return "0%"
|
1126
|
+
else
|
1127
|
+
return percent_value.round(sig_dig).to_s + "%"
|
1128
|
+
end
|
1129
|
+
end
|
1130
|
+
|
1131
|
+
# returns 0.50 / s ie {{value}} / {{unit}}
|
1132
|
+
def format_rate(amount, unit='s', sig_dig=2)
|
1133
|
+
if amount.to_f == 0
|
1134
|
+
return "0.00" + " / " + unit.to_s
|
1135
|
+
else
|
1136
|
+
rtn = amount.to_f.round(2).to_s
|
1137
|
+
parts = rtn.split('.')
|
1138
|
+
# number_str = format_number(parts[0])
|
1139
|
+
number_str = parts[0].to_s
|
1140
|
+
decimal_str = "#{parts[1]}".ljust(sig_dig, "0")
|
1141
|
+
number_str + "." + decimal_str
|
1142
|
+
return number_str + "." + decimal_str + " / " + unit.to_s
|
1143
|
+
end
|
1144
|
+
end
|
1145
|
+
|
1118
1146
|
end
|
@@ -31,6 +31,28 @@ module Morpheus::Cli::ProvisioningHelper
|
|
31
31
|
@instance_types_interface
|
32
32
|
end
|
33
33
|
|
34
|
+
def instance_type_layouts_interface
|
35
|
+
# @api_client.instance_types
|
36
|
+
raise "#{self.class} has not defined @library_layouts" if @library_layouts_interface.nil?
|
37
|
+
@library_layouts_interface
|
38
|
+
end
|
39
|
+
|
40
|
+
def clouds_interface
|
41
|
+
# @api_client.instance_types
|
42
|
+
raise "#{self.class} has not defined @clouds_interface" if @clouds_interface.nil?
|
43
|
+
@clouds_interface
|
44
|
+
end
|
45
|
+
|
46
|
+
def cloud_datastores_interface
|
47
|
+
raise "#{self.class} has not defined @clouds_datastores_interface" if @clouds_datastores_interface.nil?
|
48
|
+
@clouds_datastores_interface
|
49
|
+
end
|
50
|
+
|
51
|
+
def accounts_interface
|
52
|
+
raise "#{self.class} has not defined @accounts_interface" if @accounts_interface.nil?
|
53
|
+
@accounts_interface
|
54
|
+
end
|
55
|
+
|
34
56
|
def get_available_groups(refresh=false)
|
35
57
|
if !@available_groups || refresh
|
36
58
|
option_results = options_interface.options_for_source('groups',{})
|
@@ -62,6 +84,22 @@ module Morpheus::Cli::ProvisioningHelper
|
|
62
84
|
return group["clouds"]
|
63
85
|
end
|
64
86
|
|
87
|
+
def get_available_accounts(refresh=false)
|
88
|
+
if !@available_accounts || refresh
|
89
|
+
@available_accounts = accounts_interface.list()['accounts']
|
90
|
+
end
|
91
|
+
@available_accounts
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_available_plans(refresh=false)
|
95
|
+
if !@available_plans || refresh
|
96
|
+
@available_plans = instances_interface.search_plans['searchPlans'].collect {|it|
|
97
|
+
{"name" => it["name"], "value" => it["id"]}
|
98
|
+
}
|
99
|
+
end
|
100
|
+
@available_plans
|
101
|
+
end
|
102
|
+
|
65
103
|
def find_group_by_id_for_provisioning(val)
|
66
104
|
groups = get_available_groups()
|
67
105
|
group = groups.find {|it| it["id"].to_s == val.to_s }
|
@@ -208,6 +246,15 @@ module Morpheus::Cli::ProvisioningHelper
|
|
208
246
|
return instance
|
209
247
|
end
|
210
248
|
|
249
|
+
def find_instance_type_layout_by_id(layout_id, id)
|
250
|
+
json_results = instance_type_layouts_interface.get(layout_id, id)
|
251
|
+
if json_results['instanceTypeLayout'].empty?
|
252
|
+
print_red_alert "Instance type layout not found by id #{id}"
|
253
|
+
exit 1
|
254
|
+
end
|
255
|
+
json_results['instanceTypeLayout']
|
256
|
+
end
|
257
|
+
|
211
258
|
def find_workflow_by_name_or_id(val)
|
212
259
|
if val.to_s =~ /\A\d{1,}\Z/
|
213
260
|
return find_workflow_by_id(val)
|
@@ -244,8 +291,12 @@ module Morpheus::Cli::ProvisioningHelper
|
|
244
291
|
end
|
245
292
|
end
|
246
293
|
|
294
|
+
def find_cloud_resource_pool_by_name_or_id(cloud_id, val)
|
295
|
+
(val.to_s =~ /\A\d{1,}\Z/) ? find_cloud_resource_pool_by_id(cloud_id, val) : find_cloud_resource_pool_by_name(cloud_id, val)
|
296
|
+
end
|
297
|
+
|
247
298
|
def get_provision_type_for_zone_type(zone_type_id)
|
248
|
-
|
299
|
+
clouds_interface.cloud_type(zone_type_id)['zoneType']['provisionTypes'].first rescue nil
|
249
300
|
end
|
250
301
|
|
251
302
|
# prompts user for all the configuartion options for a particular instance
|
@@ -254,8 +305,10 @@ module Morpheus::Cli::ProvisioningHelper
|
|
254
305
|
#puts "prompt_new_instance() #{options}"
|
255
306
|
print reset # clear colors
|
256
307
|
options[:options] ||= {}
|
308
|
+
|
257
309
|
# Group
|
258
|
-
default_group =
|
310
|
+
default_group = find_group_by_name_or_id_for_provisioning(options[:default_group] || @active_group_id) if options[:default_group] || @active_group_id
|
311
|
+
|
259
312
|
group_id = nil
|
260
313
|
group = options[:group] ? find_group_by_name_or_id_for_provisioning(options[:group]) : nil
|
261
314
|
if group
|
@@ -278,8 +331,11 @@ module Morpheus::Cli::ProvisioningHelper
|
|
278
331
|
available_clouds = get_available_clouds(group_id)
|
279
332
|
cloud_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'cloud', 'type' => 'select', 'fieldLabel' => 'Cloud', 'selectOptions' => get_available_clouds(group_id), 'required' => true, 'description' => 'Select Cloud.', 'defaultValue' => options[:default_cloud] ? options[:default_cloud] : nil}],options[:options],api_client,{groupId: group_id})
|
280
333
|
cloud_id = cloud_prompt['cloud']
|
281
|
-
cloud = available_clouds.find {|it| it['id'] == cloud_id.to_i || it['name'] == cloud_id.to_s }
|
282
334
|
end
|
335
|
+
|
336
|
+
cloud = clouds_interface.get(cloud_id)['zone']
|
337
|
+
cloud_type = cloud['zoneType'] || {}
|
338
|
+
|
283
339
|
# Instance Type
|
284
340
|
instance_type_code = nil
|
285
341
|
if options[:instance_type_code]
|
@@ -302,9 +358,38 @@ module Morpheus::Cli::ProvisioningHelper
|
|
302
358
|
elsif options[:options]['instance'] && options[:options]['instance']['name']
|
303
359
|
options[:options]['name'] = options[:options]['instance']['name']
|
304
360
|
end
|
305
|
-
|
306
|
-
instance_name
|
307
|
-
|
361
|
+
|
362
|
+
while instance_name.nil? do
|
363
|
+
name_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Instance Name', 'type' => 'text', 'required' => options[:name_required], 'defaultValue' => options[:default_name]}], options[:options])
|
364
|
+
|
365
|
+
if name_prompt['name'].nil? && !options[:name_required]
|
366
|
+
break
|
367
|
+
else
|
368
|
+
if instances_interface.get({name: name_prompt['name']})['instances'].empty?
|
369
|
+
instance_name = name_prompt['name']
|
370
|
+
else
|
371
|
+
print_red_alert "Name must be unique"
|
372
|
+
|
373
|
+
if options[:default_name] == name_prompt['name']
|
374
|
+
options[:default_name] += '-2'
|
375
|
+
end
|
376
|
+
end
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
# config
|
381
|
+
config = {}
|
382
|
+
if cloud_type['code'] == 'amazon' && (cloud['config'] || {})['isVpc'] == 'false' && (cloud['config'] || {})['vpc'] == ''
|
383
|
+
config['isEC2'] = true
|
384
|
+
else
|
385
|
+
config['isEC2'] = false
|
386
|
+
if cloud_type['code'] == 'amazon' && (cloud['config'] || {})['isVpc'] == 'true' && (cloud['config'] || {})['vpc'] != ''
|
387
|
+
config['isVpcSelectable'] = false
|
388
|
+
config['resourcePoolId'] = cloud['config']['vpc']
|
389
|
+
else
|
390
|
+
config['isVpcSelectable'] = true
|
391
|
+
end
|
392
|
+
end
|
308
393
|
|
309
394
|
payload = {
|
310
395
|
'zoneId' => cloud_id,
|
@@ -319,7 +404,8 @@ module Morpheus::Cli::ProvisioningHelper
|
|
319
404
|
'instanceType' => {
|
320
405
|
'code' => instance_type_code
|
321
406
|
}
|
322
|
-
}
|
407
|
+
},
|
408
|
+
'config' => config
|
323
409
|
}
|
324
410
|
|
325
411
|
# allow arbitrary -O values passed by the user
|
@@ -361,45 +447,53 @@ module Morpheus::Cli::ProvisioningHelper
|
|
361
447
|
payload['instance']['tags'] = v_prompt['tags'].split(',').collect {|it| it.to_s.strip }.compact.uniq if !v_prompt['tags'].empty?
|
362
448
|
|
363
449
|
# Version and Layout
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
default_layout_value =
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
if
|
379
|
-
|
380
|
-
|
450
|
+
if options[:version]
|
451
|
+
version_value = options[:version]
|
452
|
+
else
|
453
|
+
available_versions = options_interface.options_for_source('instanceVersions',{groupId: group_id, cloudId: cloud_id, instanceTypeId: instance_type['id']})['data']
|
454
|
+
default_version_value = payload['instance']['version'] ? payload['instance']['version'] : payload['version']
|
455
|
+
default_layout_value = payload['instance']['layout'] ? payload['instance']['layout'] : payload['layout']
|
456
|
+
if default_layout_value && default_layout_value.is_a?(Hash)
|
457
|
+
default_layout_value = default_layout_value['id']
|
458
|
+
end
|
459
|
+
# JD: version is always nil because it is not stored in the blueprint or config !!
|
460
|
+
# so for now, infer the version from the layout
|
461
|
+
# requires api 3.6.2 to get "layouts" from /options/versions
|
462
|
+
if default_layout_value && default_version_value.to_s.empty?
|
463
|
+
available_versions.each do |available_version|
|
464
|
+
if available_version["layouts"]
|
465
|
+
selected_layout = available_version["layouts"].find {|it| it["value"].to_s == default_layout_value.to_s || it["id"].to_s == default_layout_value.to_s || it["code"].to_s == default_layout_value.to_s }
|
466
|
+
if selected_layout
|
467
|
+
default_version_value = available_version["value"]
|
468
|
+
break
|
469
|
+
end
|
381
470
|
end
|
382
471
|
end
|
383
472
|
end
|
384
|
-
end
|
385
473
|
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
474
|
+
# do not require version if a layout is passed
|
475
|
+
version_value = default_version_value
|
476
|
+
version_is_required = default_layout_value.nil?
|
477
|
+
if default_layout_value.nil? && options[:options]["layout"].nil? && options[:always_prompt] != true
|
478
|
+
#version_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'version', 'type' => 'select', 'fieldLabel' => 'Version', 'optionSource' => 'instanceVersions', 'required' => true, 'skipSingleOption' => true, 'autoPickOption' => true, 'description' => 'Select which version of the instance type to be provisioned.', 'defaultValue' => default_version_value}],options[:options],api_client,{groupId: group_id, cloudId: cloud_id, instanceTypeId: instance_type['id']})
|
479
|
+
version_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'version', 'type' => 'select', 'fieldLabel' => 'Version', 'selectOptions' => available_versions, 'required' => version_is_required, 'skipSingleOption' => true, 'autoPickOption' => true, 'description' => 'Select which version of the instance type to be provisioned.', 'defaultValue' => default_version_value}],options[:options],api_client,{groupId: group_id, cloudId: cloud_id, instanceTypeId: instance_type['id']})
|
480
|
+
version_value = version_prompt['version']
|
481
|
+
end
|
393
482
|
end
|
483
|
+
|
394
484
|
# JD: there is a bug here, the version needs to be passed perhaps? or the optionSource methods need updating...
|
395
485
|
# could just allow for now ...
|
396
486
|
# if options[:options]["layout"]
|
397
487
|
# layout_id = options[:options]["layout"]
|
398
488
|
# ...
|
399
489
|
# end
|
400
|
-
|
401
|
-
|
402
|
-
|
490
|
+
layout_id = options[:layout].to_i if options[:layout]
|
491
|
+
|
492
|
+
if !layout_id
|
493
|
+
layout_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'layout', 'type' => 'select', 'fieldLabel' => 'Layout', 'optionSource' => 'layoutsForCloud', 'required' => true, 'description' => 'Select which configuration of the instance type to be provisioned.', 'defaultValue' => default_layout_value}],options[:options],api_client,{groupId: group_id, cloudId: cloud_id, instanceTypeId: instance_type['id'], version: version_value, creatable: true})['layout']
|
494
|
+
end
|
495
|
+
|
496
|
+
layout = find_instance_type_layout_by_id(instance_type['id'], layout_id.to_i)
|
403
497
|
if !layout
|
404
498
|
print_red_alert "Layout not found by id #{layout_id}"
|
405
499
|
exit 1
|
@@ -407,22 +501,31 @@ module Morpheus::Cli::ProvisioningHelper
|
|
407
501
|
payload['instance']['layout'] = {'id' => layout['id']}
|
408
502
|
|
409
503
|
# prompt for service plan
|
410
|
-
service_plans_json = @instances_interface.service_plans({zoneId: cloud_id, layoutId:
|
504
|
+
service_plans_json = @instances_interface.service_plans({zoneId: cloud_id, layoutId: layout['id'], siteId: group_id})
|
411
505
|
service_plans = service_plans_json["plans"]
|
412
|
-
|
413
|
-
|
414
|
-
if payload['plan']
|
415
|
-
default_plan = payload['plan']
|
416
|
-
elsif payload['instance'] && payload['instance']['plan']
|
417
|
-
default_plan = payload['instance']['plan']
|
418
|
-
end
|
419
|
-
default_plan_value = default_plan.is_a?(Hash) ? default_plan['id'] : default_plan
|
420
|
-
plan_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'servicePlan', 'type' => 'select', 'fieldLabel' => 'Plan', 'selectOptions' => service_plans_dropdown, 'required' => true, 'description' => 'Choose the appropriately sized plan for this instance', 'defaultValue' => default_plan_value}],options[:options])
|
421
|
-
plan_id = plan_prompt['servicePlan']
|
422
|
-
service_plan = service_plans.find {|sp| sp["id"] == plan_id.to_i }
|
506
|
+
service_plan = service_plans.find {|sp| sp['id'] == options[:service_plan].to_i} if options[:service_plan]
|
507
|
+
|
423
508
|
if !service_plan
|
424
|
-
|
425
|
-
|
509
|
+
service_plans_dropdown = service_plans.collect {|sp| {'name' => sp["name"], 'value' => sp["id"], 'code' => sp['code']} } # already sorted
|
510
|
+
default_plan = nil
|
511
|
+
if payload['plan']
|
512
|
+
default_plan = payload['plan']
|
513
|
+
elsif payload['instance'] && payload['instance']['plan']
|
514
|
+
default_plan = payload['instance']['plan']
|
515
|
+
end
|
516
|
+
|
517
|
+
if options[:default_plan] && service_plans_dropdown.find {|sp| [sp["name"], sp["value"].to_s, sp["code"]].include?(options[:default_plan].to_s)}
|
518
|
+
default_plan_value = options[:default_plan]
|
519
|
+
else
|
520
|
+
default_plan_value = options[:default_plan] || (default_plan.is_a?(Hash) ? default_plan['id'] : default_plan)
|
521
|
+
end
|
522
|
+
plan_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'servicePlan', 'type' => 'select', 'fieldLabel' => 'Plan', 'selectOptions' => service_plans_dropdown, 'required' => true, 'description' => 'Choose the appropriately sized plan for this instance', 'defaultValue' => default_plan_value}],options[:options])
|
523
|
+
plan_id = plan_prompt['servicePlan']
|
524
|
+
service_plan = service_plans.find {|sp| sp["id"] == plan_id.to_i }
|
525
|
+
if !service_plan
|
526
|
+
print_red_alert "Plan not found by id #{plan_id}"
|
527
|
+
exit 1
|
528
|
+
end
|
426
529
|
end
|
427
530
|
#todo: consolidate these, instances api looks for instance.plan.id and apps looks for plan.id
|
428
531
|
payload['plan'] = {'id' => service_plan["id"], 'code' => service_plan["code"], 'name' => service_plan["name"]}
|
@@ -458,50 +561,87 @@ module Morpheus::Cli::ProvisioningHelper
|
|
458
561
|
# pluck out the resourcePoolId option type to prompt for
|
459
562
|
resource_pool_option_type = option_type_list.find {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
|
460
563
|
option_type_list = option_type_list.reject {|opt| ['resourcePool','resourcePoolId','azureResourceGroupId'].include?(opt['fieldName']) }
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
564
|
+
resource_pool_options = @options_interface.options_for_source('zonePools', {groupId: group_id, siteId: group_id, zoneId: cloud_id, cloudId: cloud_id, instanceTypeId: instance_type['id'], planId: service_plan["id"], layoutId: layout["id"]})['data']
|
565
|
+
resource_pool = resource_pool_options.find {|opt| opt['id'] == options[:resource_pool].to_i} if options[:resource_pool]
|
566
|
+
|
567
|
+
if resource_pool
|
568
|
+
pool_id = resource_pool['id']
|
569
|
+
else
|
570
|
+
if options[:default_resource_pool]
|
571
|
+
default_resource_pool = resource_pool_options.find {|rp| rp['id'] == options[:default_resource_pool]}
|
572
|
+
end
|
573
|
+
resource_pool_option_type ||= {'fieldContext' => 'config', 'fieldName' => 'resourcePoolId', 'type' => 'select', 'fieldLabel' => 'Resource Pool', 'selectOptions' => resource_pool_options, 'required' => true, 'skipSingleOption' => true, 'description' => 'Select resource pool.', 'defaultValue' => default_resource_pool ? default_resource_pool['name'] : nil}
|
574
|
+
resource_pool_prompt = Morpheus::Cli::OptionTypes.prompt([resource_pool_option_type],options[:options],api_client,{})
|
575
|
+
resource_pool_prompt.deep_compact!
|
576
|
+
payload.deep_merge!(resource_pool_prompt)
|
577
|
+
resource_pool = Morpheus::Cli::OptionTypes.get_last_select()
|
578
|
+
if resource_pool_option_type['fieldContext'] && resource_pool_prompt[resource_pool_option_type['fieldContext']]
|
579
|
+
pool_id = resource_pool_prompt[resource_pool_option_type['fieldContext']][resource_pool_option_type['fieldName']]
|
580
|
+
elsif resource_pool_prompt[resource_pool_option_type['fieldName']]
|
581
|
+
pool_id = resource_pool_prompt[resource_pool_option_type['fieldName']]
|
582
|
+
end
|
470
583
|
end
|
471
584
|
end
|
472
585
|
|
473
586
|
# remove host selection for kubernetes
|
474
|
-
if resource_pool
|
475
|
-
|
476
|
-
|
477
|
-
|
587
|
+
if resource_pool
|
588
|
+
payload['config']['poolProviderType'] = resource_pool['providerType'] if resource_pool['providerType']
|
589
|
+
if resource_pool['providerType'] == 'kubernetes'
|
590
|
+
option_type_list = option_type_list.reject {|opt| ['provisionServerId'].include?(opt['fieldName'])}
|
591
|
+
end
|
592
|
+
|
593
|
+
# add selectable datastores for resource pool
|
594
|
+
if options[:select_datastore]
|
595
|
+
service_plan['datastores'] = {'cluster' => [], 'store' => []}
|
596
|
+
selectable_datastores = cloud_datastores_interface.selectable(cloud_id, {'siteId' => group_id, 'resourcePoolId' => resource_pool['id']})
|
597
|
+
['cluster', 'store'].each do |type|
|
598
|
+
service_plan['datastores'][type] ||= []
|
599
|
+
selectable_datastores[type].reject { |ds| service_plan['datastores'][type].find {|it| it['id'] == ds['id']} }.each { |ds|
|
600
|
+
service_plan['datastores'][type] << ds
|
601
|
+
}
|
602
|
+
end
|
603
|
+
|
604
|
+
if layout['provisionType'] && layout['provisionType']['supportsAutoDatastore']
|
605
|
+
service_plan['autoOptions'] ||= []
|
606
|
+
if service_plan['datastores']['cluster'].count > 0 && !service_plan['autoOptions'].find {|it| it['id'] == 'autoCluster'}
|
607
|
+
service_plan['autoOptions'] << {'id' => 'autoCluster', 'name' => 'Auto - Cluster'}
|
608
|
+
end
|
609
|
+
if service_plan['datastores']['store'].count > 0 && !service_plan['autoOptions'].find {|it| it['id'] == 'auto'}
|
610
|
+
service_plan['autoOptions'] << {'id' => 'auto', 'name' => 'Auto - Datastore'}
|
611
|
+
end
|
612
|
+
end
|
613
|
+
end
|
478
614
|
end
|
479
615
|
|
480
616
|
# plan_info has this property already..
|
481
617
|
# has_datastore = layout["provisionType"] && layout["provisionType"]["id"] && layout["provisionType"]["hasDatastore"]
|
482
618
|
# service_plan['hasDatastore'] = has_datastore
|
483
619
|
|
620
|
+
# set root volume name if has mounts
|
621
|
+
mounts = (layout['mounts'] || []).reject {|it| !it['canPersist']}
|
622
|
+
if mounts.count > 0
|
623
|
+
options[:root_volume_name] = mounts[0]['shortName']
|
624
|
+
end
|
625
|
+
|
484
626
|
# prompt for volumes
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
end
|
490
|
-
# end
|
627
|
+
volumes = prompt_volumes(service_plan, options, api_client, {zoneId: cloud_id, layoutId: layout['id'], siteId: group_id})
|
628
|
+
if !volumes.empty?
|
629
|
+
payload['volumes'] = volumes
|
630
|
+
end
|
491
631
|
|
492
|
-
#
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
end
|
500
|
-
rescue RestClient::Exception => e
|
501
|
-
print yellow,"Unable to load network options. Proceeding...",reset,"\n"
|
502
|
-
print_rest_exception(e, options) if Morpheus::Logging.debug?
|
632
|
+
# prompt networks
|
633
|
+
if layout["provisionType"] && layout["provisionType"]["id"] && layout["provisionType"]["hasNetworks"] # && layout["provisionType"]["supportsNetworkSelection"]
|
634
|
+
# prompt for network interfaces (if supported)
|
635
|
+
begin
|
636
|
+
network_interfaces = prompt_network_interfaces(cloud_id, layout["provisionType"]["id"], pool_id, options)
|
637
|
+
if !network_interfaces.empty?
|
638
|
+
payload['networkInterfaces'] = network_interfaces
|
503
639
|
end
|
640
|
+
rescue RestClient::Exception => e
|
641
|
+
print yellow,"Unable to load network options. Proceeding...",reset,"\n"
|
642
|
+
print_rest_exception(e, options) if Morpheus::Logging.debug?
|
504
643
|
end
|
644
|
+
end
|
505
645
|
# end
|
506
646
|
|
507
647
|
# Security Groups
|
@@ -511,27 +651,34 @@ module Morpheus::Cli::ProvisioningHelper
|
|
511
651
|
# ok.. seed data has changed and serverTypes do not have this optionType anymore...
|
512
652
|
if sg_option_type.nil?
|
513
653
|
if layout["provisionType"] && (layout["provisionType"]["code"] == 'amazon')
|
514
|
-
sg_option_type = {'fieldContext' => 'config', 'fieldName' => 'securityId', 'type' => 'select', 'fieldLabel' => 'Security Group', 'optionSource' => 'amazonSecurityGroup', 'required' => true, 'description' => 'Select security group.'}
|
654
|
+
sg_option_type = {'fieldContext' => 'config', 'fieldName' => 'securityId', 'type' => 'select', 'fieldLabel' => 'Security Group', 'optionSource' => 'amazonSecurityGroup', 'required' => true, 'description' => 'Select security group.', 'defaultValue' => options[:default_security_group]}
|
515
655
|
end
|
516
656
|
end
|
517
657
|
has_security_groups = !!sg_option_type
|
518
658
|
if options[:security_groups]
|
519
659
|
payload['securityGroups'] = options[:security_groups].collect {|sg_id| {'id' => sg_id} }
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
payload['securityGroups'] = security_groups_array.collect {|sg_id| {'id' => sg_id} }
|
525
|
-
end
|
660
|
+
elsif has_security_groups
|
661
|
+
security_groups_array = prompt_security_groups(sg_option_type, {zoneId: cloud_id, poolId: pool_id}, options)
|
662
|
+
if !security_groups_array.empty?
|
663
|
+
payload['securityGroups'] = security_groups_array.collect {|sg_id| {'id' => sg_id} }
|
526
664
|
end
|
527
665
|
end
|
528
666
|
|
529
|
-
|
530
667
|
# prompt for option types
|
531
668
|
api_params = {groupId: group_id, cloudId: cloud_id, zoneId: cloud_id, instanceTypeId: instance_type['id'], version: version_value}
|
532
669
|
api_params['config'] = payload['config'] if payload['config']
|
533
670
|
api_params['poolId'] = payload['config']['resourcePoolId'] if payload['config'] && payload['config']['resourcePoolId']
|
534
671
|
|
672
|
+
# set option type defaults from config
|
673
|
+
if options[:default_config]
|
674
|
+
options[:default_config].each do |k,v|
|
675
|
+
if v && !(v.kind_of?(Array) && v.empty?)
|
676
|
+
option_type = option_type_list.find {|ot| ot['fieldContext'] == 'config' && ot['fieldName'] == k}
|
677
|
+
option_type['defaultValue'] = v if option_type
|
678
|
+
end
|
679
|
+
end
|
680
|
+
end
|
681
|
+
|
535
682
|
instance_config_payload = Morpheus::Cli::OptionTypes.prompt(option_type_list, options[:options], @api_client, api_params)
|
536
683
|
payload.deep_merge!(instance_config_payload)
|
537
684
|
|
@@ -558,10 +705,10 @@ module Morpheus::Cli::ProvisioningHelper
|
|
558
705
|
# returns array of volumes based on service plan options (plan_info)
|
559
706
|
def prompt_volumes(plan_info, options={}, api_client=nil, api_params={})
|
560
707
|
#puts "Configure Volumes:"
|
561
|
-
|
708
|
+
# return [] if plan_info['noDisks']
|
562
709
|
|
710
|
+
no_prompt = (options[:no_prompt] || (options[:options] && options[:options][:no_prompt]))
|
563
711
|
volumes = []
|
564
|
-
|
565
712
|
plan_size = nil
|
566
713
|
if plan_info['maxStorage']
|
567
714
|
plan_size = plan_info['maxStorage'].to_i / (1024 * 1024 * 1024)
|
@@ -615,7 +762,7 @@ module Morpheus::Cli::ProvisioningHelper
|
|
615
762
|
|
616
763
|
field_context = "rootVolume"
|
617
764
|
|
618
|
-
volume_label = 'root'
|
765
|
+
volume_label = options[:root_volume_name] || 'root'
|
619
766
|
volume = {
|
620
767
|
'id' => -1,
|
621
768
|
'rootVolume' => true,
|
@@ -634,7 +781,8 @@ module Morpheus::Cli::ProvisioningHelper
|
|
634
781
|
storage_type_id = nil
|
635
782
|
storage_type = nil
|
636
783
|
else
|
637
|
-
|
784
|
+
default_storage_type = root_storage_types.find {|t| t['value'].to_s == volume['storageType'].to_s}
|
785
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'storageType', 'type' => 'select', 'fieldLabel' => 'Root Storage Type', 'selectOptions' => root_storage_types, 'required' => true, 'skipSingleOption' => true, 'description' => 'Choose a storage type.', 'defaultValue' => default_storage_type ? default_storage_type['name'] : volume['storageType']}], options[:options])
|
638
786
|
storage_type_id = v_prompt[field_context]['storageType']
|
639
787
|
storage_type = plan_info['storageTypes'].find {|i| i['id'] == storage_type_id.to_i }
|
640
788
|
volume['storageType'] = storage_type_id
|
@@ -670,8 +818,10 @@ module Morpheus::Cli::ProvisioningHelper
|
|
670
818
|
#volume['sizeId'] = nil #volume.delete('sizeId')
|
671
819
|
end
|
672
820
|
if !datastore_options.empty?
|
673
|
-
|
821
|
+
default_datastore = datastore_options.find {|ds| ds['value'].to_s == volume['datastoreId'].to_s}
|
822
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'datastoreId', 'type' => 'select', 'fieldLabel' => 'Root Datastore', 'selectOptions' => datastore_options, 'required' => true, 'description' => 'Choose a datastore.', 'defaultValue' => default_datastore ? default_datastore['name'] : volume['datastoreId']}], options[:options])
|
674
823
|
volume['datastoreId'] = v_prompt[field_context]['datastoreId']
|
824
|
+
volume['hasDatastore'] = true
|
675
825
|
end
|
676
826
|
|
677
827
|
volumes << volume
|
@@ -736,6 +886,7 @@ module Morpheus::Cli::ProvisioningHelper
|
|
736
886
|
if !datastore_options.empty?
|
737
887
|
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'datastoreId', 'type' => 'select', 'fieldLabel' => "Disk #{volume_index} Datastore", 'selectOptions' => datastore_options, 'required' => true, 'description' => 'Choose a datastore.', 'defaultValue' => volume['datastoreId']}], options[:options])
|
738
888
|
volume['datastoreId'] = v_prompt[field_context]['datastoreId']
|
889
|
+
volume['hasDatastore'] = true
|
739
890
|
end
|
740
891
|
|
741
892
|
volumes << volume
|
@@ -1056,6 +1207,10 @@ module Morpheus::Cli::ProvisioningHelper
|
|
1056
1207
|
if network_groups
|
1057
1208
|
networks = network_groups + networks
|
1058
1209
|
end
|
1210
|
+
network_subnets = zone_network_data['networkSubnets']
|
1211
|
+
if network_subnets
|
1212
|
+
networks += network_subnets
|
1213
|
+
end
|
1059
1214
|
network_interface_types = (zone_network_data['networkTypes'] || []).sort { |x,y| x['displayOrder'] <=> y['displayOrder'] }
|
1060
1215
|
enable_network_type_selection = (zone_network_data['enableNetworkTypeSelection'] == 'on' || zone_network_data['enableNetworkTypeSelection'] == true)
|
1061
1216
|
has_networks = zone_network_data["hasNetworks"] == true
|
@@ -1102,11 +1257,26 @@ module Morpheus::Cli::ProvisioningHelper
|
|
1102
1257
|
network_interface = options[:options]['networkInterfaces'][interface_index]
|
1103
1258
|
end
|
1104
1259
|
|
1260
|
+
default_network_id = network_interface['networkId'] || network_interface['id']
|
1261
|
+
|
1262
|
+
if network_interface['network'] && network_interface['network']['id']
|
1263
|
+
if network_interface['network']['subnet']
|
1264
|
+
default_network_id = "subnet-#{network_interface['network']['subnet']}"
|
1265
|
+
elsif network_interface['network']['group']
|
1266
|
+
default_network_id = "networkGroup-#{network_interface['network']['group']}"
|
1267
|
+
else
|
1268
|
+
default_network_id = "network-#{network_interface['network']['id']}"
|
1269
|
+
end
|
1270
|
+
end
|
1271
|
+
|
1272
|
+
default_network_value = (network_options.find {|n| n['value'] == default_network_id} || {})['name']
|
1273
|
+
|
1105
1274
|
# choose network
|
1106
|
-
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'networkId', 'type' => 'select', 'fieldLabel' => "Network", 'selectOptions' => network_options, 'required' => true, 'skipSingleOption' => false, 'description' => 'Choose a network for this interface.', 'defaultValue' =>
|
1275
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'networkId', 'type' => 'select', 'fieldLabel' => "Network", 'selectOptions' => network_options, 'required' => true, 'skipSingleOption' => false, 'description' => 'Choose a network for this interface.', 'defaultValue' => default_network_value}], options[:options])
|
1107
1276
|
network_interface['network'] = {}
|
1108
1277
|
network_interface['network']['id'] = v_prompt[field_context]['networkId'].to_s
|
1109
1278
|
selected_network = networks.find {|it| it["id"].to_s == network_interface['network']['id'] }
|
1279
|
+
network_options.reject! {|it| it['value'] == v_prompt[field_context]['networkId']}
|
1110
1280
|
|
1111
1281
|
if !selected_network
|
1112
1282
|
print_red_alert "Network not found by id #{network_interface['network']['id']}!"
|
@@ -1115,7 +1285,8 @@ module Morpheus::Cli::ProvisioningHelper
|
|
1115
1285
|
|
1116
1286
|
# choose network interface type
|
1117
1287
|
if enable_network_type_selection && !network_interface_type_options.empty?
|
1118
|
-
|
1288
|
+
default_interface_type_value = (network_interface_type_options.find {|t| t['value'].to_s == network_interface['networkInterfaceTypeId'].to_s} || {})['name']
|
1289
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'networkInterfaceTypeId', 'type' => 'select', 'fieldLabel' => "Network Interface Type", 'selectOptions' => network_interface_type_options, 'required' => true, 'skipSingleOption' => true, 'description' => 'Choose a network interface type.', 'defaultValue' => default_interface_type_value}], options[:options])
|
1119
1290
|
network_interface['networkInterfaceTypeId'] = v_prompt[field_context]['networkInterfaceTypeId'].to_i
|
1120
1291
|
end
|
1121
1292
|
|
@@ -1140,7 +1311,7 @@ module Morpheus::Cli::ProvisioningHelper
|
|
1140
1311
|
interface_index += 1
|
1141
1312
|
if options[:options] && options[:options]['networkInterfaces'] && options[:options]['networkInterfaces'][interface_index]
|
1142
1313
|
add_another_interface = true
|
1143
|
-
elsif max_networks && network_interfaces.size >= max_networks
|
1314
|
+
elsif (max_networks && network_interfaces.size >= max_networks) || network_options.count == 0
|
1144
1315
|
add_another_interface = false
|
1145
1316
|
else
|
1146
1317
|
has_another_interface = options[:options] && options[:options]["networkInterface#{interface_index+1}"]
|
@@ -1211,12 +1382,14 @@ module Morpheus::Cli::ProvisioningHelper
|
|
1211
1382
|
def prompt_security_groups(sg_option_type, api_params, options)
|
1212
1383
|
no_prompt = (options[:no_prompt] || (options[:options] && options[:options][:no_prompt]))
|
1213
1384
|
security_groups_array = []
|
1214
|
-
|
1215
1385
|
sg_required = sg_option_type['required']
|
1216
1386
|
sg_index = 0
|
1217
1387
|
add_another_sg = sg_required || (!no_prompt && Morpheus::Cli::OptionTypes.confirm("Add a security group?", {default: false}))
|
1218
1388
|
while add_another_sg do
|
1219
1389
|
cur_sg_option_type = sg_option_type.merge({'required' => (sg_index == 0 ? sg_required : false)})
|
1390
|
+
if sg_index == 0 && !options[:default_security_group].nil?
|
1391
|
+
cur_sg_option_type['defaultValue'] = options[:default_security_group]
|
1392
|
+
end
|
1220
1393
|
field_context = cur_sg_option_type['fieldContext']
|
1221
1394
|
field_name = cur_sg_option_type['fieldName']
|
1222
1395
|
v_prompt = Morpheus::Cli::OptionTypes.prompt([cur_sg_option_type], options[:options], api_client, api_params)
|
@@ -1331,4 +1504,289 @@ module Morpheus::Cli::ProvisioningHelper
|
|
1331
1504
|
[{'name' => 'Dev', 'value' => 'dev'}, {'name' => 'Test', 'value' => 'qa'}, {'name' => 'Staging', 'value' => 'staging'}, {'name' => 'Production', 'value' => 'production'}]
|
1332
1505
|
end
|
1333
1506
|
|
1507
|
+
def add_perms_options(opts, options, excludes = [])
|
1508
|
+
if !excludes.include?('groups')
|
1509
|
+
opts.on('--group-access-all [on|off]', String, "Toggle Access for all groups.") do |val|
|
1510
|
+
options[:groupAccessAll] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
|
1511
|
+
end
|
1512
|
+
opts.on('--group-access LIST', Array, "Group Access, comma separated list of group IDs.") do |list|
|
1513
|
+
if list.size == 1 && list[0] == 'null' # hacky way to clear it
|
1514
|
+
options[:groupAccessList] = []
|
1515
|
+
else
|
1516
|
+
options[:groupAccessList] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
1517
|
+
end
|
1518
|
+
end
|
1519
|
+
if !excludes.include?('groupDefaults')
|
1520
|
+
opts.on('--group-defaults LIST', Array, "Group Default Selection, comma separated list of group IDs") do |list|
|
1521
|
+
if list.size == 1 && list[0] == 'null' # hacky way to clear it
|
1522
|
+
options[:groupDefaultsList] = []
|
1523
|
+
else
|
1524
|
+
options[:groupDefaultsList] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
1525
|
+
end
|
1526
|
+
end
|
1527
|
+
end
|
1528
|
+
end
|
1529
|
+
|
1530
|
+
if !excludes.include?('plans')
|
1531
|
+
opts.on('--plan-access-all [on|off]', String, "Toggle Access for all service plans.") do |val|
|
1532
|
+
options[:planAccessAll] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == ''
|
1533
|
+
end
|
1534
|
+
opts.on('--plan-access LIST', Array, "Service Plan Access, comma separated list of plan IDs.") do |list|
|
1535
|
+
if list.size == 1 && list[0] == 'null' # hacky way to clear it
|
1536
|
+
options[:planAccessList] = []
|
1537
|
+
else
|
1538
|
+
options[:planAccessList] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
1539
|
+
end
|
1540
|
+
end
|
1541
|
+
opts.on('--plan-defaults LIST', Array, "Plan Default Selection, comma separated list of plan IDs") do |list|
|
1542
|
+
if list.size == 1 && list[0] == 'null' # hacky way to clear it
|
1543
|
+
options[:planDefaultsList] = []
|
1544
|
+
else
|
1545
|
+
options[:planDefaultsList] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
1546
|
+
end
|
1547
|
+
end
|
1548
|
+
end
|
1549
|
+
|
1550
|
+
if !excludes.include?('visibility')
|
1551
|
+
opts.on('--visibility VISIBILITY', String, "Visibility [private|public]") do |val|
|
1552
|
+
options[:visibility] = val
|
1553
|
+
end
|
1554
|
+
end
|
1555
|
+
|
1556
|
+
if !excludes.include?('tenants')
|
1557
|
+
opts.on('--tenants LIST', Array, "Tenant Access, comma separated list of account IDs") do |list|
|
1558
|
+
if list.size == 1 && list[0] == 'null' # hacky way to clear it
|
1559
|
+
options[:tenants] = []
|
1560
|
+
else
|
1561
|
+
options[:tenants] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
1562
|
+
end
|
1563
|
+
end
|
1564
|
+
end
|
1565
|
+
end
|
1566
|
+
|
1567
|
+
def prompt_permissions(options, excludes = [])
|
1568
|
+
all_groups = nil
|
1569
|
+
group_access = nil
|
1570
|
+
all_plans = nil
|
1571
|
+
plan_access = nil
|
1572
|
+
|
1573
|
+
# Group Access
|
1574
|
+
if !excludes.include?('groups')
|
1575
|
+
if !options[:groupAccessAll].nil?
|
1576
|
+
all_groups = options[:groupAccessAll]
|
1577
|
+
end
|
1578
|
+
|
1579
|
+
if !options[:groupAccessList].empty?
|
1580
|
+
group_access = options[:groupAccessList].collect {|site_id| {'id' => site_id.to_i}} || []
|
1581
|
+
elsif !options[:no_prompt]
|
1582
|
+
available_groups = options[:available_groups] || get_available_groups
|
1583
|
+
|
1584
|
+
if available_groups.empty?
|
1585
|
+
#print_red_alert "No available groups"
|
1586
|
+
#exit 1
|
1587
|
+
elsif available_groups.count > 1
|
1588
|
+
available_groups.unshift({"id" => '0', "name" => "All", "value" => "all"})
|
1589
|
+
|
1590
|
+
# default to all
|
1591
|
+
group_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'group', 'type' => 'select', 'fieldLabel' => 'Group Access', 'selectOptions' => available_groups, 'required' => false, 'description' => 'Add Group Access.'}], options[:options], @api_client, {})['group']
|
1592
|
+
|
1593
|
+
if !group_id.nil?
|
1594
|
+
if group_id == 'all'
|
1595
|
+
all_groups = true
|
1596
|
+
else
|
1597
|
+
group_access = (excludes.include?('groupDefaults') ? [{'id' => group_id}] : [{'id' => group_id, 'default' => Morpheus::Cli::OptionTypes.confirm("Set '#{available_groups.find{|it| it['value'] == group_id}['name']}' as default?", {:default => false})}])
|
1598
|
+
end
|
1599
|
+
available_groups = available_groups.reject {|it| it['value'] == group_id}
|
1600
|
+
|
1601
|
+
while !group_id.nil? && !available_groups.empty? && Morpheus::Cli::OptionTypes.confirm("Add another group access?", {:default => false})
|
1602
|
+
group_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'group', 'type' => 'select', 'fieldLabel' => 'Group Access', 'selectOptions' => available_groups, 'required' => false, 'description' => 'Add Group Access.'}], options[:options], @api_client, {})['group']
|
1603
|
+
|
1604
|
+
if !group_id.nil?
|
1605
|
+
if group_id == 'all'
|
1606
|
+
all_groups = true
|
1607
|
+
else
|
1608
|
+
group_access ||= []
|
1609
|
+
group_access << (excludes.include?('groupDefaults') ? {'id' => group_id} : {'id' => group_id, 'default' => Morpheus::Cli::OptionTypes.confirm("Set '#{available_groups.find{|it| it['value'] == group_id}['name']}' as default?", {:default => false})})
|
1610
|
+
end
|
1611
|
+
available_groups = available_groups.reject {|it| it['value'] == group_id}
|
1612
|
+
end
|
1613
|
+
end
|
1614
|
+
end
|
1615
|
+
end
|
1616
|
+
end
|
1617
|
+
end
|
1618
|
+
|
1619
|
+
# Plan Access
|
1620
|
+
if !excludes.include?('plans')
|
1621
|
+
if !options[:planAccessAll].nil?
|
1622
|
+
all_plans = options[:planAccessAll]
|
1623
|
+
end
|
1624
|
+
|
1625
|
+
if !options[:planAccessList].empty?
|
1626
|
+
plan_access = options[:planAccessList].collect {|plan_id| {'id' => plan_id.to_i}}
|
1627
|
+
elsif !options[:no_prompt]
|
1628
|
+
available_plans = options[:available_plans] || get_available_plans
|
1629
|
+
|
1630
|
+
if available_plans.empty?
|
1631
|
+
#print_red_alert "No available plans"
|
1632
|
+
#exit 1
|
1633
|
+
elsif !available_plans.empty? && !options[:no_prompt]
|
1634
|
+
available_plans.unshift({"id" => '0', "name" => "All", "value" => "all"})
|
1635
|
+
|
1636
|
+
# default to all
|
1637
|
+
plan_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'plan', 'type' => 'select', 'fieldLabel' => 'Service Plan Access', 'selectOptions' => available_plans, 'required' => false, 'description' => 'Add Service Plan Access.'}], options[:options], @api_client, {})['plan']
|
1638
|
+
|
1639
|
+
if !plan_id.nil?
|
1640
|
+
if plan_id == 'all'
|
1641
|
+
all_plans = true
|
1642
|
+
else
|
1643
|
+
plan_access = [{'id' => plan_id, 'default' => Morpheus::Cli::OptionTypes.confirm("Set '#{available_plans.find{|it| it['id'] == plan_id}['name']}' as default?", {:default => false})}]
|
1644
|
+
end
|
1645
|
+
|
1646
|
+
available_plans = available_plans.reject {|it| it['value'] == plan_id}
|
1647
|
+
|
1648
|
+
while !plan_id.nil? && !available_plans.empty? && Morpheus::Cli::OptionTypes.confirm("Add another service plan access?", {:default => false})
|
1649
|
+
plan_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'plan', 'type' => 'select', 'fieldLabel' => 'Service Plan Access', 'selectOptions' => available_plans, 'required' => false, 'description' => 'Add Service Plan Access.'}], options[:options], @api_client, {})['plan']
|
1650
|
+
|
1651
|
+
if !plan_id.nil?
|
1652
|
+
if plan_id == 'all'
|
1653
|
+
all_plans = true
|
1654
|
+
else
|
1655
|
+
plan_access ||= []
|
1656
|
+
plan_access << {'id' => plan_id, 'default' => Morpheus::Cli::OptionTypes.confirm("Set '#{available_plans.find{|it| it['value'] == plan_id}['name']}' as default?", {:default => false})}
|
1657
|
+
end
|
1658
|
+
available_plans = available_plans.reject {|it| it['value'] == plan_id}
|
1659
|
+
end
|
1660
|
+
end
|
1661
|
+
end
|
1662
|
+
end
|
1663
|
+
end
|
1664
|
+
end
|
1665
|
+
|
1666
|
+
resource_perms = {}
|
1667
|
+
resource_perms['all'] = all_groups if !all_groups.nil?
|
1668
|
+
resource_perms['sites'] = group_access if !group_access.nil?
|
1669
|
+
resource_perms['allPlans'] = all_plans if !all_plans.nil?
|
1670
|
+
resource_perms['plans'] = plan_access if !plan_access.nil?
|
1671
|
+
|
1672
|
+
permissions = {'resourcePermissions' => resource_perms}
|
1673
|
+
|
1674
|
+
available_accounts = get_available_accounts.collect {|it| {'name' => it['name'], 'value' => it['id']}}
|
1675
|
+
accounts = []
|
1676
|
+
|
1677
|
+
# Prompts for multi tenant
|
1678
|
+
if available_accounts.count > 1
|
1679
|
+
visibility = options[:visibility]
|
1680
|
+
|
1681
|
+
if !visibility && !options[:no_prompt]
|
1682
|
+
visibility = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'visibility', 'fieldLabel' => 'Tenant Permissions Visibility', 'type' => 'select', 'defaultValue' => 'private', 'required' => true, 'selectOptions' => [{'name' => 'Private', 'value' => 'private'},{'name' => 'Public', 'value' => 'public'}]}], options[:options], @api_client, {})['visibility']
|
1683
|
+
end
|
1684
|
+
|
1685
|
+
permissions['resourcePool'] = {'visibility' => visibility} if visibility
|
1686
|
+
|
1687
|
+
# Tenants
|
1688
|
+
if !excludes.include?('tenants')
|
1689
|
+
if !options[:tenants].nil?
|
1690
|
+
accounts = options[:tenants].collect {|id| id.to_i}
|
1691
|
+
elsif !options[:no_prompt]
|
1692
|
+
account_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'account_id', 'type' => 'select', 'fieldLabel' => 'Add Tenant', 'selectOptions' => available_accounts, 'required' => false, 'description' => 'Add Tenant Permissions.'}], options[:options], @api_client, {})['account_id']
|
1693
|
+
|
1694
|
+
if !account_id.nil?
|
1695
|
+
accounts << account_id
|
1696
|
+
available_accounts = available_accounts.reject {|it| it['value'] == account_id}
|
1697
|
+
|
1698
|
+
while !available_accounts.empty? && (account_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'account_id', 'type' => 'select', 'fieldLabel' => 'Add Another Tenant', 'selectOptions' => available_accounts, 'required' => false, 'description' => 'Add Tenant Permissions.'}], options[:options], @api_client, {})['account_id'])
|
1699
|
+
if !account_id.nil?
|
1700
|
+
accounts << account_id
|
1701
|
+
available_accounts = available_accounts.reject {|it| it['value'] == account_id}
|
1702
|
+
end
|
1703
|
+
end
|
1704
|
+
end
|
1705
|
+
end
|
1706
|
+
permissions['tenantPermissions'] = {'accounts' => accounts}
|
1707
|
+
end
|
1708
|
+
end
|
1709
|
+
permissions
|
1710
|
+
end
|
1711
|
+
|
1712
|
+
def print_permissions(permissions, excludes = [])
|
1713
|
+
if permissions.nil?
|
1714
|
+
print_h2 "Permissions"
|
1715
|
+
print yellow,"No permissions found.",reset,"\n"
|
1716
|
+
else
|
1717
|
+
if !permissions['resourcePermissions'].nil?
|
1718
|
+
if !excludes.include?('groups')
|
1719
|
+
print_h2 "Group Access"
|
1720
|
+
|
1721
|
+
if excludes.include?('groupDefaults')
|
1722
|
+
groups = []
|
1723
|
+
groups << 'All' if permissions['resourcePermissions']['all']
|
1724
|
+
groups += permissions['resourcePermissions']['sites'].collect {|it| it['name']} if permissions['resourcePermissions']['sites']
|
1725
|
+
|
1726
|
+
if groups.count > 0
|
1727
|
+
print cyan,"#{groups.join(', ')}".center(20)
|
1728
|
+
else
|
1729
|
+
print yellow,"No group access",reset,"\n"
|
1730
|
+
end
|
1731
|
+
print "\n"
|
1732
|
+
else
|
1733
|
+
rows = []
|
1734
|
+
if permissions['resourcePermissions']['all']
|
1735
|
+
rows.push({group: 'All'})
|
1736
|
+
end
|
1737
|
+
if permissions['resourcePermissions']['sites']
|
1738
|
+
permissions['resourcePermissions']['sites'].each do |site|
|
1739
|
+
rows.push({group: site['name'], default: site['default'] ? 'Yes' : ''})
|
1740
|
+
end
|
1741
|
+
end
|
1742
|
+
if rows.empty?
|
1743
|
+
print yellow,"No group access",reset,"\n"
|
1744
|
+
else
|
1745
|
+
columns = [:group, :default]
|
1746
|
+
print cyan
|
1747
|
+
print as_pretty_table(rows, columns)
|
1748
|
+
end
|
1749
|
+
end
|
1750
|
+
end
|
1751
|
+
|
1752
|
+
if !excludes.include?('plans')
|
1753
|
+
print_h2 "Plan Access"
|
1754
|
+
rows = []
|
1755
|
+
if permissions['resourcePermissions']['allPlans']
|
1756
|
+
rows.push({plan: 'All'})
|
1757
|
+
end
|
1758
|
+
if permissions['resourcePermissions']['plans']
|
1759
|
+
permissions['resourcePermissions']['plans'].each do |plan|
|
1760
|
+
rows.push({plan: plan['name'], default: plan['default'] ? 'Yes' : ''})
|
1761
|
+
end
|
1762
|
+
end
|
1763
|
+
if rows.empty?
|
1764
|
+
print yellow,"No plan access",reset,"\n"
|
1765
|
+
else
|
1766
|
+
columns = [:plan, :default]
|
1767
|
+
print cyan
|
1768
|
+
print as_pretty_table(rows, columns)
|
1769
|
+
end
|
1770
|
+
end
|
1771
|
+
|
1772
|
+
if !excludes.include?('tenants')
|
1773
|
+
if !permissions['tenantPermissions'].nil?
|
1774
|
+
print_h2 "Tenant Permissions"
|
1775
|
+
if !permissions['resourcePool'].nil?
|
1776
|
+
print cyan
|
1777
|
+
print "Visibility: #{permissions['resourcePool']['visibility'].to_s.capitalize}".center(20)
|
1778
|
+
print "\n"
|
1779
|
+
end
|
1780
|
+
if !permissions['tenantPermissions'].nil?
|
1781
|
+
print cyan
|
1782
|
+
print "Accounts: #{permissions['tenantPermissions']['accounts'].join(', ')}".center(20)
|
1783
|
+
print "\n"
|
1784
|
+
end
|
1785
|
+
end
|
1786
|
+
end
|
1787
|
+
print "\n"
|
1788
|
+
end
|
1789
|
+
end
|
1790
|
+
end
|
1791
|
+
|
1334
1792
|
end
|