morpheus-cli 5.0.2 → 5.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/lib/morpheus/api/api_client.rb +4 -0
- data/lib/morpheus/api/instances_interface.rb +9 -2
- data/lib/morpheus/api/servers_interface.rb +7 -0
- data/lib/morpheus/api/service_catalog_interface.rb +89 -0
- data/lib/morpheus/cli.rb +2 -1
- data/lib/morpheus/cli/apps.rb +3 -23
- data/lib/morpheus/cli/{catalog_command.rb → catalog_item_types_command.rb} +182 -67
- data/lib/morpheus/cli/cli_command.rb +25 -1
- data/lib/morpheus/cli/containers_command.rb +0 -24
- data/lib/morpheus/cli/cypher_command.rb +6 -2
- data/lib/morpheus/cli/health_command.rb +57 -0
- data/lib/morpheus/cli/hosts.rb +85 -9
- data/lib/morpheus/cli/instances.rb +85 -68
- data/lib/morpheus/cli/library_option_lists_command.rb +1 -1
- data/lib/morpheus/cli/library_option_types_command.rb +5 -2
- data/lib/morpheus/cli/mixins/accounts_helper.rb +5 -1
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +76 -0
- data/lib/morpheus/cli/option_types.rb +10 -10
- data/lib/morpheus/cli/roles.rb +193 -155
- data/lib/morpheus/cli/service_catalog_command.rb +1474 -0
- data/lib/morpheus/cli/tasks.rb +9 -11
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/virtual_images.rb +162 -68
- data/lib/morpheus/formatters.rb +34 -9
- metadata +5 -4
- data/lib/morpheus/cli/mixins/catalog_helper.rb +0 -66
@@ -270,7 +270,7 @@ class Morpheus::Cli::LibraryOptionListsCommand
|
|
270
270
|
else
|
271
271
|
payload = {}
|
272
272
|
payload.deep_merge!({'optionTypeList' => parse_passed_options(options)})
|
273
|
-
list_payload = Morpheus::Cli::OptionTypes.no_prompt(
|
273
|
+
list_payload = Morpheus::Cli::OptionTypes.no_prompt(update_option_type_list_option_types(), options[:options], @api_client)
|
274
274
|
if list_payload['type'] == 'rest'
|
275
275
|
# parse Source Headers
|
276
276
|
if !(payload['optionTypeList']['config'] && payload['optionTypeList']['config']['sourceHeaders'])
|
@@ -129,7 +129,7 @@ class Morpheus::Cli::LibraryOptionTypesCommand
|
|
129
129
|
|
130
130
|
print_h1 "Option Type Details"
|
131
131
|
print cyan
|
132
|
-
|
132
|
+
columns = {
|
133
133
|
"ID" => 'id',
|
134
134
|
"Name" => 'name',
|
135
135
|
"Description" => 'description',
|
@@ -138,11 +138,14 @@ class Morpheus::Cli::LibraryOptionTypesCommand
|
|
138
138
|
# "Field Name" => 'fieldName',
|
139
139
|
"Full Field Name" => lambda {|it| [it['fieldContext'], it['fieldName']].select {|it| !it.to_s.empty? }.join('.') },
|
140
140
|
"Type" => lambda {|it| it['type'].to_s.capitalize },
|
141
|
+
"Option List" => lambda {|it| it['optionList'] ? it['optionList']['name'] : nil },
|
141
142
|
"Placeholder" => 'placeHolder',
|
142
143
|
"Default Value" => 'defaultValue',
|
143
144
|
"Required" => lambda {|it| format_boolean(it['required']) },
|
144
145
|
"Export As Tag" => lambda {|it| it['exportMeta'].nil? ? '' : format_boolean(it['exportMeta']) },
|
145
|
-
}
|
146
|
+
}
|
147
|
+
columns.delete("Option List") if option_type['optionList'].nil?
|
148
|
+
print as_description_list(option_type, columns, options)
|
146
149
|
print reset,"\n"
|
147
150
|
return 0
|
148
151
|
rescue RestClient::Exception => e
|
@@ -401,7 +401,7 @@ module Morpheus::Cli::AccountsHelper
|
|
401
401
|
end
|
402
402
|
|
403
403
|
def get_access_string(access, return_color=cyan)
|
404
|
-
get_access_color(access) + access + return_color
|
404
|
+
get_access_color(access) + access.to_s + return_color.to_s
|
405
405
|
# access ||= 'none'
|
406
406
|
# if access == 'none'
|
407
407
|
# "#{white}#{access.to_s}#{return_color}"
|
@@ -426,10 +426,14 @@ module Morpheus::Cli::AccountsHelper
|
|
426
426
|
# Examples: format_permission_access("read")
|
427
427
|
# format_permission_access("custom", "full,custom,none")
|
428
428
|
def format_access_string(access, access_levels=nil, return_color=cyan)
|
429
|
+
# nevermind all this, just colorized access level
|
430
|
+
return get_access_string(access, return_color)
|
431
|
+
|
429
432
|
access = access.to_s.downcase.strip
|
430
433
|
if access.empty?
|
431
434
|
access = "none"
|
432
435
|
end
|
436
|
+
|
433
437
|
if access_levels.nil?
|
434
438
|
access_levels = ["none","read","user","full"]
|
435
439
|
elsif access_levels.is_a?(Array)
|
@@ -2180,6 +2180,82 @@ module Morpheus::Cli::ProvisioningHelper
|
|
2180
2180
|
return ports
|
2181
2181
|
end
|
2182
2182
|
|
2183
|
+
def format_instance_status(instance, return_color=cyan)
|
2184
|
+
out = ""
|
2185
|
+
status_string = instance['status'].to_s
|
2186
|
+
if status_string == 'running'
|
2187
|
+
out << "#{green}#{status_string.upcase}#{return_color}"
|
2188
|
+
elsif status_string == 'provisioning'
|
2189
|
+
out << "#{cyan}#{status_string.upcase}#{return_color}"
|
2190
|
+
elsif status_string == 'stopped' or status_string == 'failed'
|
2191
|
+
out << "#{red}#{status_string.upcase}#{return_color}"
|
2192
|
+
else
|
2193
|
+
out << "#{yellow}#{status_string.upcase}#{return_color}"
|
2194
|
+
end
|
2195
|
+
out
|
2196
|
+
end
|
2197
|
+
|
2198
|
+
def format_instance_connection_string(instance)
|
2199
|
+
if !instance['connectionInfo'].nil? && instance['connectionInfo'].empty? == false
|
2200
|
+
connection_string = "#{instance['connectionInfo'][0]['ip']}:#{instance['connectionInfo'][0]['port']}"
|
2201
|
+
end
|
2202
|
+
end
|
2203
|
+
|
2204
|
+
def format_app_status(app, return_color=cyan)
|
2205
|
+
out = ""
|
2206
|
+
status_string = app['status'] || app['appStatus'] || ''
|
2207
|
+
if status_string == 'running'
|
2208
|
+
out = "#{green}#{status_string.upcase}#{return_color}"
|
2209
|
+
elsif status_string == 'provisioning'
|
2210
|
+
out = "#{cyan}#{status_string.upcase}#{cyan}"
|
2211
|
+
elsif status_string == 'stopped' or status_string == 'failed'
|
2212
|
+
out = "#{red}#{status_string.upcase}#{return_color}"
|
2213
|
+
elsif status_string == 'unknown'
|
2214
|
+
out = "#{yellow}#{status_string.upcase}#{return_color}"
|
2215
|
+
elsif status_string == 'warning' && app['instanceCount'].to_i == 0
|
2216
|
+
# show this instead of WARNING
|
2217
|
+
out = "#{cyan}EMPTY#{return_color}"
|
2218
|
+
else
|
2219
|
+
out = "#{yellow}#{status_string.upcase}#{return_color}"
|
2220
|
+
end
|
2221
|
+
out
|
2222
|
+
end
|
2223
|
+
|
2224
|
+
def format_container_status(container, return_color=cyan)
|
2225
|
+
out = ""
|
2226
|
+
status_string = container['status'].to_s
|
2227
|
+
if status_string == 'running'
|
2228
|
+
out << "#{green}#{status_string.upcase}#{return_color}"
|
2229
|
+
elsif status_string == 'provisioning'
|
2230
|
+
out << "#{cyan}#{status_string.upcase}#{return_color}"
|
2231
|
+
elsif status_string == 'stopped' or status_string == 'failed'
|
2232
|
+
out << "#{red}#{status_string.upcase}#{return_color}"
|
2233
|
+
else
|
2234
|
+
out << "#{yellow}#{status_string.upcase}#{return_color}"
|
2235
|
+
end
|
2236
|
+
out
|
2237
|
+
end
|
2238
|
+
|
2239
|
+
def format_container_connection_string(container)
|
2240
|
+
if !container['ports'].nil? && container['ports'].empty? == false
|
2241
|
+
connection_string = "#{container['ip']}:#{container['ports'][0]['external']}"
|
2242
|
+
else
|
2243
|
+
# eh? more logic needed here i think, see taglib morph:containerLocationMenu
|
2244
|
+
connection_string = "#{container['ip']}"
|
2245
|
+
end
|
2246
|
+
end
|
2247
|
+
|
2248
|
+
def format_instance_container_display_name(instance, plural=false)
|
2249
|
+
#<span class="info-label">${[null,'docker'].contains(instance.layout?.provisionType?.code) ? 'Containers' : 'Virtual Machines'}:</span> <span class="info-value">${instance.containers?.size()}</span>
|
2250
|
+
v = plural ? "Containers" : "Container"
|
2251
|
+
if instance && instance['layout'] && instance['layout'].key?("provisionTypeCode")
|
2252
|
+
if [nil, 'docker'].include?(instance['layout']["provisionTypeCode"])
|
2253
|
+
v = plural ? "Virtual Machines" : "Virtual Machine"
|
2254
|
+
end
|
2255
|
+
end
|
2256
|
+
return v
|
2257
|
+
end
|
2258
|
+
|
2183
2259
|
def format_blueprint_type(type_code)
|
2184
2260
|
return type_code.to_s # just show it as is
|
2185
2261
|
if type_code.to_s.empty?
|
@@ -142,25 +142,25 @@ module Morpheus
|
|
142
142
|
value = value.to_s.include?('.') ? value.to_f : value.to_i
|
143
143
|
# these select prompts should just fall down through below, with the extra params no_prompt, use_value
|
144
144
|
elsif option_type['type'] == 'select'
|
145
|
-
value = select_prompt(option_type.merge({'defaultValue' => value, 'defaultInputValue' => input_value}), api_client, (api_params || {}).merge(results), true)
|
145
|
+
value = select_prompt(option_type.merge({'defaultValue' => value, 'defaultInputValue' => input_value}), api_client, (option_type['noParams'] ? {} : (api_params || {}).merge(results)), true)
|
146
146
|
elsif option_type['type'] == 'multiSelect'
|
147
147
|
# support value as csv like "thing1, thing2"
|
148
148
|
value_list = value.is_a?(String) ? value.parse_csv.collect {|v| v ? v.to_s.strip : v } : [value].flatten
|
149
149
|
input_value_list = input_value.is_a?(String) ? input_value.parse_csv.collect {|v| v ? v.to_s.strip : v } : [input_value].flatten
|
150
150
|
select_value_list = []
|
151
151
|
value_list.each_with_index do |v, i|
|
152
|
-
select_value_list << select_prompt(option_type.merge({'defaultValue' => v, 'defaultInputValue' => input_value_list[i]}), api_client, (api_params || {}).merge(results), true)
|
152
|
+
select_value_list << select_prompt(option_type.merge({'defaultValue' => v, 'defaultInputValue' => input_value_list[i]}), api_client, (option_type['noParams'] ? {} : (api_params || {}).merge(results)), true)
|
153
153
|
end
|
154
154
|
value = select_value_list
|
155
155
|
elsif option_type['type'] == 'typeahead'
|
156
|
-
value = typeahead_prompt(option_type.merge({'defaultValue' => value, 'defaultInputValue' => input_value}), api_client, (api_params || {}).merge(results), true)
|
156
|
+
value = typeahead_prompt(option_type.merge({'defaultValue' => value, 'defaultInputValue' => input_value}), api_client, (option_type['noParams'] ? {} : (api_params || {}).merge(results)), true)
|
157
157
|
elsif option_type['type'] == 'multiTypeahead'
|
158
158
|
# support value as csv like "thing1, thing2"
|
159
159
|
value_list = value.is_a?(String) ? value.parse_csv.collect {|v| v ? v.to_s.strip : v } : [value].flatten
|
160
160
|
input_value_list = input_value.is_a?(String) ? input_value.parse_csv.collect {|v| v ? v.to_s.strip : v } : [input_value].flatten
|
161
161
|
select_value_list = []
|
162
162
|
value_list.each_with_index do |v, i|
|
163
|
-
select_value_list << typeahead_prompt(option_type.merge({'defaultValue' => v, 'defaultInputValue' => input_value_list[i]}), api_client, (api_params || {}).merge(results), true)
|
163
|
+
select_value_list << typeahead_prompt(option_type.merge({'defaultValue' => v, 'defaultInputValue' => input_value_list[i]}), api_client, (option_type['noParams'] ? {} : (api_params || {}).merge(results)), true)
|
164
164
|
end
|
165
165
|
value = select_value_list
|
166
166
|
end
|
@@ -187,11 +187,11 @@ module Morpheus
|
|
187
187
|
# select type is special because it supports skipSingleOption
|
188
188
|
# and prints the available options on error
|
189
189
|
if ['select', 'multiSelect'].include?(option_type['type'])
|
190
|
-
value = select_prompt(option_type, api_client, (api_params || {}).merge(results), true)
|
190
|
+
value = select_prompt(option_type, api_client, (option_type['noParams'] ? {} : (api_params || {}).merge(results)), true)
|
191
191
|
value_found = !!value
|
192
192
|
end
|
193
193
|
if ['typeahead', 'multiTypeahead'].include?(option_type['type'])
|
194
|
-
value = typeahead_prompt(option_type, api_client, (api_params || {}).merge(results), true)
|
194
|
+
value = typeahead_prompt(option_type, api_client, (option_type['noParams'] ? {} : (api_params || {}).merge(results)), true)
|
195
195
|
value_found = !!value
|
196
196
|
end
|
197
197
|
if !value_found
|
@@ -228,11 +228,11 @@ module Morpheus
|
|
228
228
|
# I suppose the entered value should take precedence
|
229
229
|
# api_params = api_params.merge(options) # this might be good enough
|
230
230
|
# dup it
|
231
|
-
value = select_prompt(option_type, api_client, (api_params || {}).merge(results), options[:no_prompt], nil, paging_enabled)
|
231
|
+
value = select_prompt(option_type, api_client, (option_type['noParams'] ? {} : (api_params || {}).merge(results)), options[:no_prompt], nil, paging_enabled)
|
232
232
|
if value && option_type['type'] == 'multiSelect'
|
233
233
|
value = [value]
|
234
234
|
while self.confirm("Add another #{option_type['fieldLabel']}?", {:default => false}) do
|
235
|
-
if addn_value = select_prompt(option_type, api_client, (api_params || {}).merge(results), options[:no_prompt], nil, paging_enabled)
|
235
|
+
if addn_value = select_prompt(option_type, api_client, (option_type['noParams'] ? {} : (api_params || {}).merge(results)), options[:no_prompt], nil, paging_enabled)
|
236
236
|
value << addn_value
|
237
237
|
else
|
238
238
|
break
|
@@ -240,11 +240,11 @@ module Morpheus
|
|
240
240
|
end
|
241
241
|
end
|
242
242
|
elsif ['typeahead', 'multiTypeahead'].include?(option_type['type'])
|
243
|
-
value = typeahead_prompt(option_type, api_client, (api_params || {}).merge(results), options[:no_prompt], nil, paging_enabled)
|
243
|
+
value = typeahead_prompt(option_type, api_client, (option_type['noParams'] ? {} : (api_params || {}).merge(results)), options[:no_prompt], nil, paging_enabled)
|
244
244
|
if value && option_type['type'] == 'multiTypeahead'
|
245
245
|
value = [value]
|
246
246
|
while self.confirm("Add another #{option_type['fieldLabel']}?", {:default => false}) do
|
247
|
-
if addn_value = typeahead_prompt(option_type, api_client, (api_params || {}).merge(results), options[:no_prompt], nil, paging_enabled)
|
247
|
+
if addn_value = typeahead_prompt(option_type, api_client, (option_type['noParams'] ? {} : (api_params || {}).merge(results)), options[:no_prompt], nil, paging_enabled)
|
248
248
|
value << addn_value
|
249
249
|
else
|
250
250
|
break
|
data/lib/morpheus/cli/roles.rb
CHANGED
@@ -211,56 +211,70 @@ EOT
|
|
211
211
|
print cyan,"Use --permissions to list permissions","\n"
|
212
212
|
end
|
213
213
|
|
214
|
+
has_group_access = true
|
215
|
+
has_cloud_access = true
|
214
216
|
print_h2 "Global Access", options
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
217
|
+
global_access_columns = {
|
218
|
+
"Groups" => lambda {|it| get_access_string(it['globalSiteAccess']) },
|
219
|
+
"Clouds" => lambda {|it| get_access_string(it['globalZoneAccess']) },
|
220
|
+
"Instance Types" => lambda {|it| get_access_string(it['globalInstanceTypeAccess']) },
|
221
|
+
"Blueprints" => lambda {|it| get_access_string(it['globalAppTemplateAccess'] || it['globalBlueprintAccess']) },
|
222
|
+
"Catalog Item Types" => lambda {|it| get_access_string(it['globalCatalogItemTypeAccess']) },
|
223
|
+
}
|
224
|
+
if role['roleType'].to_s.downcase == 'account'
|
225
|
+
global_access_columns.delete("Groups")
|
226
|
+
has_group_access = false
|
227
|
+
else
|
228
|
+
global_access_columns.delete("Clouds")
|
229
|
+
has_cloud_access = false
|
230
|
+
end
|
231
|
+
puts as_pretty_table([json_response], global_access_columns, options)
|
232
|
+
|
233
|
+
if has_group_access
|
234
|
+
#print_h2 "Group Access: #{get_access_string(json_response['globalSiteAccess'])}", options
|
235
|
+
print cyan
|
236
|
+
if json_response['globalSiteAccess'] == 'custom'
|
237
|
+
print_h2 "Group Access", options
|
238
|
+
if options[:include_group_access]
|
239
|
+
rows = json_response['sites'].collect do |it|
|
240
|
+
{
|
241
|
+
name: it['name'],
|
242
|
+
access: format_access_string(it['access'], ["none","read","full"]),
|
243
|
+
}
|
244
|
+
end
|
245
|
+
print as_pretty_table(rows, [:name, :access], options)
|
246
|
+
else
|
247
|
+
print cyan,"Use -g, --group-access to list custom access","\n"
|
233
248
|
end
|
234
|
-
print
|
249
|
+
print reset,"\n"
|
235
250
|
else
|
236
|
-
print
|
251
|
+
# print "\n"
|
252
|
+
# print cyan,bold,"Group Access: #{get_access_string(json_response['globalSiteAccess'])}",reset,"\n"
|
237
253
|
end
|
238
|
-
print reset,"\n"
|
239
|
-
else
|
240
|
-
# print "\n"
|
241
|
-
# print cyan,bold,"Group Access: #{get_access_string(json_response['globalSiteAccess'])}",reset,"\n"
|
242
254
|
end
|
243
255
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
256
|
+
if has_cloud_access
|
257
|
+
print cyan
|
258
|
+
#puts "Cloud Access: #{get_access_string(json_response['globalZoneAccess'])}"
|
259
|
+
#print "\n"
|
260
|
+
if json_response['globalZoneAccess'] == 'custom'
|
261
|
+
print_h2 "Cloud Access", options
|
262
|
+
if options[:include_cloud_access]
|
263
|
+
rows = json_response['zones'].collect do |it|
|
264
|
+
{
|
265
|
+
name: it['name'],
|
266
|
+
access: format_access_string(it['access'], ["none","read","full"]),
|
267
|
+
}
|
268
|
+
end
|
269
|
+
print as_pretty_table(rows, [:name, :access], options)
|
270
|
+
else
|
271
|
+
print cyan,"Use -c, --cloud-access to list custom access","\n"
|
255
272
|
end
|
256
|
-
print
|
273
|
+
print reset,"\n"
|
257
274
|
else
|
258
|
-
print
|
275
|
+
# print "\n"
|
276
|
+
# print cyan,bold,"Cloud Access: #{get_access_string(json_response['globalZoneAccess'])}",reset,"\n"
|
259
277
|
end
|
260
|
-
print reset,"\n"
|
261
|
-
else
|
262
|
-
# print "\n"
|
263
|
-
# print cyan,bold,"Cloud Access: #{get_access_string(json_response['globalZoneAccess'])}",reset,"\n"
|
264
278
|
end
|
265
279
|
|
266
280
|
print cyan
|
@@ -326,7 +340,7 @@ EOT
|
|
326
340
|
end
|
327
341
|
print as_pretty_table(rows, [:name, :access], options)
|
328
342
|
else
|
329
|
-
print cyan,"Use
|
343
|
+
print cyan,"Use --catalog-item-type-access to list custom access","\n"
|
330
344
|
end
|
331
345
|
else
|
332
346
|
# print "\n"
|
@@ -335,7 +349,8 @@ EOT
|
|
335
349
|
|
336
350
|
|
337
351
|
persona_permissions = json_response['personaPermissions'] || json_response['personas'] || []
|
338
|
-
if options[:
|
352
|
+
# if options[:include_personas_access]
|
353
|
+
if persona_permissions
|
339
354
|
print_h2 "Persona Access", options
|
340
355
|
rows = persona_permissions.collect do |it|
|
341
356
|
{
|
@@ -552,7 +567,7 @@ EOT
|
|
552
567
|
options = {}
|
553
568
|
params = {}
|
554
569
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
555
|
-
opts.banner = subcommand_usage("[
|
570
|
+
opts.banner = subcommand_usage("[role] [options]")
|
556
571
|
build_option_type_options(opts, options, update_role_option_types)
|
557
572
|
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
558
573
|
end
|
@@ -630,7 +645,7 @@ EOT
|
|
630
645
|
def remove(args)
|
631
646
|
options = {}
|
632
647
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
633
|
-
opts.banner = subcommand_usage("[
|
648
|
+
opts.banner = subcommand_usage("[role]")
|
634
649
|
build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
|
635
650
|
end
|
636
651
|
optparse.parse!(args)
|
@@ -770,41 +785,46 @@ EOT
|
|
770
785
|
group_name = nil
|
771
786
|
access_value = nil
|
772
787
|
do_all = false
|
788
|
+
allowed_access_values = ['full', 'read', 'none']
|
773
789
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
774
|
-
opts.banner = subcommand_usage("[
|
790
|
+
opts.banner = subcommand_usage("[role] [group] [access]")
|
775
791
|
opts.on( '-g', '--group GROUP', "Group name or id" ) do |val|
|
776
792
|
group_name = val
|
777
793
|
end
|
778
794
|
opts.on( nil, '--all', "Update all groups at once." ) do
|
779
795
|
do_all = true
|
780
796
|
end
|
781
|
-
opts.on( '--access VALUE', String, "Access value [
|
797
|
+
opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
|
782
798
|
access_value = val
|
783
799
|
end
|
784
800
|
build_common_options(opts, options, [:json, :dry_run, :remote])
|
785
801
|
opts.footer = "Update role access for a group or all groups.\n" +
|
786
|
-
"[
|
802
|
+
"[role] is required. This is the name or id of a role.\n" +
|
787
803
|
"--group or --all is required. This is the name or id of a group.\n" +
|
788
|
-
"--access is required. This is the new access value."
|
804
|
+
"--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
|
789
805
|
end
|
790
806
|
optparse.parse!(args)
|
791
|
-
if args.count < 1
|
792
|
-
puts optparse
|
793
|
-
return 1
|
794
|
-
end
|
795
|
-
name = args[0]
|
796
|
-
# support old usage: [name] [group] [access]
|
797
|
-
group_name ||= args[1]
|
798
|
-
access_value ||= args[2]
|
799
807
|
|
800
|
-
|
801
|
-
|
802
|
-
|
808
|
+
# usage: update-group-access [role] [access] --all
|
809
|
+
# update-group-access [role] [group] [access]
|
810
|
+
name = args[0]
|
811
|
+
if do_all
|
812
|
+
verify_args!(args:args, optparse:optparse, min:1, max:2)
|
813
|
+
access_value = args[1] if args[1]
|
814
|
+
else
|
815
|
+
verify_args!(args:args, optparse:optparse, min:1, max:3)
|
816
|
+
group_id = args[1] if args[1]
|
817
|
+
access_value = args[2] if args[2]
|
818
|
+
end
|
819
|
+
if !group_id && !do_all
|
820
|
+
raise_command_error("missing required argument: [group] or --all", optparse)
|
821
|
+
end
|
822
|
+
if !access_value
|
823
|
+
raise_command_error("missing required argument: [access]", optparse)
|
803
824
|
end
|
804
|
-
|
805
825
|
access_value = access_value.to_s.downcase
|
806
|
-
|
807
|
-
|
826
|
+
if !allowed_access_values.include?(access_value)
|
827
|
+
raise_command_error("invalid access value: #{access_value}", optparse)
|
808
828
|
puts optparse
|
809
829
|
return 1
|
810
830
|
end
|
@@ -915,6 +935,7 @@ EOT
|
|
915
935
|
cloud_name = nil
|
916
936
|
access_value = nil
|
917
937
|
do_all = false
|
938
|
+
allowed_access_values = ['full', 'read', 'none']
|
918
939
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
919
940
|
opts.banner = subcommand_usage("[name]")
|
920
941
|
opts.on( '-c', '--cloud CLOUD', "Cloud name or id" ) do |val|
|
@@ -924,7 +945,7 @@ EOT
|
|
924
945
|
opts.on( nil, '--all', "Update all clouds at once." ) do
|
925
946
|
do_all = true
|
926
947
|
end
|
927
|
-
opts.on( '--access VALUE', String, "Access value [
|
948
|
+
opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
|
928
949
|
access_value = val
|
929
950
|
end
|
930
951
|
opts.on( '-g', '--group GROUP', "Group to find cloud in" ) do |val|
|
@@ -932,32 +953,34 @@ EOT
|
|
932
953
|
end
|
933
954
|
build_common_options(opts, options, [:json, :dry_run, :remote])
|
934
955
|
opts.footer = "Update role access for a cloud or all clouds.\n" +
|
935
|
-
"[
|
956
|
+
"[role] is required. This is the name or id of a role.\n" +
|
936
957
|
"--cloud or --all is required. This is the name or id of a cloud.\n" +
|
937
|
-
"--access is required. This is the new access value."
|
958
|
+
"--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
|
938
959
|
end
|
939
960
|
optparse.parse!(args)
|
940
961
|
|
941
|
-
|
942
|
-
|
943
|
-
return 1
|
944
|
-
end
|
962
|
+
# usage: update-cloud-access [role] [access] --all
|
963
|
+
# update-cloud-access [role] [cloud] [access]
|
945
964
|
name = args[0]
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
965
|
+
if do_all
|
966
|
+
verify_args!(args:args, optparse:optparse, min:1, max:2)
|
967
|
+
access_value = args[1] if args[1]
|
968
|
+
else
|
969
|
+
verify_args!(args:args, optparse:optparse, min:1, max:3)
|
970
|
+
cloud_id = args[1] if args[1]
|
971
|
+
access_value = args[2] if args[2]
|
972
|
+
end
|
973
|
+
if !cloud_id && !do_all
|
974
|
+
raise_command_error("missing required argument: [cloud] or --all", optparse)
|
975
|
+
end
|
976
|
+
if !access_value
|
977
|
+
raise_command_error("missing required argument: [access]", optparse)
|
953
978
|
end
|
954
|
-
puts "cloud_name is : #{cloud_name}"
|
955
|
-
puts "access_value is : #{access_value}"
|
956
979
|
access_value = access_value.to_s.downcase
|
957
|
-
|
958
|
-
|
980
|
+
if !allowed_access_values.include?(access_value)
|
981
|
+
raise_command_error("invalid access value: #{access_value}", optparse)
|
959
982
|
puts optparse
|
960
|
-
|
983
|
+
return 1
|
961
984
|
end
|
962
985
|
|
963
986
|
connect(options)
|
@@ -1025,10 +1048,10 @@ EOT
|
|
1025
1048
|
end
|
1026
1049
|
|
1027
1050
|
def update_global_instance_type_access(args)
|
1028
|
-
usage = "Usage: morpheus roles update-global-instance-type-access [
|
1051
|
+
usage = "Usage: morpheus roles update-global-instance-type-access [role] [full|custom|none]"
|
1029
1052
|
options = {}
|
1030
1053
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1031
|
-
opts.banner = subcommand_usage("[
|
1054
|
+
opts.banner = subcommand_usage("[role] [full|custom|none]")
|
1032
1055
|
build_common_options(opts, options, [:json, :dry_run, :remote])
|
1033
1056
|
end
|
1034
1057
|
optparse.parse!(args)
|
@@ -1077,22 +1100,23 @@ EOT
|
|
1077
1100
|
instance_type_name = nil
|
1078
1101
|
access_value = nil
|
1079
1102
|
do_all = false
|
1103
|
+
allowed_access_values = ['full', 'none']
|
1080
1104
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1081
|
-
opts.banner = subcommand_usage("[
|
1105
|
+
opts.banner = subcommand_usage("[role] [type] [access]")
|
1082
1106
|
opts.on( '--instance-type INSTANCE_TYPE', String, "Instance Type name" ) do |val|
|
1083
1107
|
instance_type_name = val
|
1084
1108
|
end
|
1085
1109
|
opts.on( nil, '--all', "Update all instance types at once." ) do
|
1086
1110
|
do_all = true
|
1087
1111
|
end
|
1088
|
-
opts.on( '--access VALUE', String, "Access value [
|
1112
|
+
opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
|
1089
1113
|
access_value = val
|
1090
1114
|
end
|
1091
1115
|
build_common_options(opts, options, [:json, :dry_run, :remote])
|
1092
1116
|
opts.footer = "Update role access for an instance type or all instance types.\n" +
|
1093
|
-
"[
|
1117
|
+
"[role] is required. This is the name or id of a role.\n" +
|
1094
1118
|
"--instance-type or --all is required. This is the name of an instance type.\n" +
|
1095
|
-
"--access is required. This is the new access value."
|
1119
|
+
"--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
|
1096
1120
|
end
|
1097
1121
|
optparse.parse!(args)
|
1098
1122
|
|
@@ -1101,7 +1125,7 @@ EOT
|
|
1101
1125
|
return 1
|
1102
1126
|
end
|
1103
1127
|
name = args[0]
|
1104
|
-
# support old usage: [
|
1128
|
+
# support old usage: [role] [instance-type] [access]
|
1105
1129
|
instance_type_name ||= args[1]
|
1106
1130
|
access_value ||= args[2]
|
1107
1131
|
|
@@ -1170,10 +1194,10 @@ EOT
|
|
1170
1194
|
end
|
1171
1195
|
|
1172
1196
|
def update_global_blueprint_access(args)
|
1173
|
-
usage = "Usage: morpheus roles update-global-blueprint-access [
|
1197
|
+
usage = "Usage: morpheus roles update-global-blueprint-access [role] [full|custom|none]"
|
1174
1198
|
options = {}
|
1175
1199
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1176
|
-
opts.banner = subcommand_usage("[
|
1200
|
+
opts.banner = subcommand_usage("[role] [full|custom|none]")
|
1177
1201
|
build_common_options(opts, options, [:json, :dry_run, :remote])
|
1178
1202
|
end
|
1179
1203
|
optparse.parse!(args)
|
@@ -1222,42 +1246,46 @@ EOT
|
|
1222
1246
|
blueprint_id = nil
|
1223
1247
|
access_value = nil
|
1224
1248
|
do_all = false
|
1249
|
+
allowed_access_values = ['full', 'none']
|
1225
1250
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1226
|
-
opts.banner = subcommand_usage("[
|
1251
|
+
opts.banner = subcommand_usage("[role] [blueprint] [access]")
|
1227
1252
|
opts.on( '--blueprint ID', String, "Blueprint ID or Name" ) do |val|
|
1228
1253
|
blueprint_id = val
|
1229
1254
|
end
|
1230
1255
|
opts.on( nil, '--all', "Update all blueprints at once." ) do
|
1231
1256
|
do_all = true
|
1232
1257
|
end
|
1233
|
-
opts.on( '--access VALUE', String, "Access value [
|
1258
|
+
opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
|
1234
1259
|
access_value = val
|
1235
1260
|
end
|
1236
1261
|
build_common_options(opts, options, [:json, :dry_run, :remote])
|
1237
1262
|
opts.footer = "Update role access for an blueprint or all blueprints.\n" +
|
1238
|
-
"[
|
1263
|
+
"[role] is required. This is the name or id of a role.\n" +
|
1239
1264
|
"--blueprint or --all is required. This is the name or id of a blueprint.\n" +
|
1240
|
-
"--access is required. This is the new access value."
|
1265
|
+
"--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
|
1241
1266
|
end
|
1242
1267
|
optparse.parse!(args)
|
1243
1268
|
|
1244
|
-
|
1245
|
-
|
1246
|
-
return 1
|
1247
|
-
end
|
1269
|
+
# usage: update-blueprint-access [role] [access] --all
|
1270
|
+
# update-blueprint-access [role] [blueprint] [access]
|
1248
1271
|
name = args[0]
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1272
|
+
if do_all
|
1273
|
+
verify_args!(args:args, optparse:optparse, min:1, max:2)
|
1274
|
+
access_value = args[1] if args[1]
|
1275
|
+
else
|
1276
|
+
verify_args!(args:args, optparse:optparse, min:1, max:3)
|
1277
|
+
blueprint_id = args[1] if args[1]
|
1278
|
+
access_value = args[2] if args[2]
|
1279
|
+
end
|
1280
|
+
if !blueprint_id && !do_all
|
1281
|
+
raise_command_error("missing required argument: [blueprint] or --all", optparse)
|
1282
|
+
end
|
1283
|
+
if !access_value
|
1284
|
+
raise_command_error("missing required argument: [access]", optparse)
|
1256
1285
|
end
|
1257
|
-
|
1258
1286
|
access_value = access_value.to_s.downcase
|
1259
|
-
|
1260
|
-
|
1287
|
+
if !allowed_access_values.include?(access_value)
|
1288
|
+
raise_command_error("invalid access value: #{access_value}", optparse)
|
1261
1289
|
puts optparse
|
1262
1290
|
return 1
|
1263
1291
|
end
|
@@ -1327,10 +1355,10 @@ EOT
|
|
1327
1355
|
end
|
1328
1356
|
|
1329
1357
|
def update_global_catalog_item_type_access(args)
|
1330
|
-
usage = "Usage: morpheus roles update-global-catalog-item-type-access [
|
1358
|
+
usage = "Usage: morpheus roles update-global-catalog-item-type-access [role] [full|custom|none]"
|
1331
1359
|
options = {}
|
1332
1360
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1333
|
-
opts.banner = subcommand_usage("[
|
1361
|
+
opts.banner = subcommand_usage("[role] [full|custom|none]")
|
1334
1362
|
build_common_options(opts, options, [:json, :dry_run, :remote])
|
1335
1363
|
end
|
1336
1364
|
optparse.parse!(args)
|
@@ -1379,42 +1407,46 @@ EOT
|
|
1379
1407
|
catalog_item_type_id = nil
|
1380
1408
|
access_value = nil
|
1381
1409
|
do_all = false
|
1410
|
+
allowed_access_values = ['full', 'none']
|
1382
1411
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1383
|
-
opts.banner = subcommand_usage("[
|
1412
|
+
opts.banner = subcommand_usage("[role] [catalog-item-type] [access]")
|
1384
1413
|
opts.on( '--catalog-item-type ID', String, "Catalog Item Type ID or Name" ) do |val|
|
1385
1414
|
catalog_item_type_id = val
|
1386
1415
|
end
|
1387
1416
|
opts.on( nil, '--all', "Update all catalog item types at once." ) do
|
1388
1417
|
do_all = true
|
1389
1418
|
end
|
1390
|
-
opts.on( '--access VALUE', String, "Access value [
|
1419
|
+
opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
|
1391
1420
|
access_value = val
|
1392
1421
|
end
|
1393
1422
|
build_common_options(opts, options, [:json, :dry_run, :remote])
|
1394
1423
|
opts.footer = "Update role access for an catalog item type or all types.\n" +
|
1395
|
-
"[
|
1424
|
+
"[role] is required. This is the name or id of a role.\n" +
|
1396
1425
|
"--catalog-item-type or --all is required. This is the name or id of a catalog item type.\n" +
|
1397
|
-
"--access is required. This is the new access value."
|
1426
|
+
"--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
|
1398
1427
|
end
|
1399
1428
|
optparse.parse!(args)
|
1400
1429
|
|
1401
|
-
|
1402
|
-
|
1403
|
-
return 1
|
1404
|
-
end
|
1430
|
+
# usage: update-catalog_item_type-access [role] [access] --all
|
1431
|
+
# update-catalog_item_type-access [role] [catalog-item-type] [access]
|
1405
1432
|
name = args[0]
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1433
|
+
if do_all
|
1434
|
+
verify_args!(args:args, optparse:optparse, min:1, max:2)
|
1435
|
+
access_value = args[1] if args[1]
|
1436
|
+
else
|
1437
|
+
verify_args!(args:args, optparse:optparse, min:1, max:3)
|
1438
|
+
catalog_item_type_id = args[1] if args[1]
|
1439
|
+
access_value = args[2] if args[2]
|
1440
|
+
end
|
1441
|
+
if !catalog_item_type_id && !do_all
|
1442
|
+
raise_command_error("missing required argument: [catalog-item-type] or --all", optparse)
|
1443
|
+
end
|
1444
|
+
if !access_value
|
1445
|
+
raise_command_error("missing required argument: [access]", optparse)
|
1413
1446
|
end
|
1414
|
-
|
1415
1447
|
access_value = access_value.to_s.downcase
|
1416
|
-
|
1417
|
-
|
1448
|
+
if !allowed_access_values.include?(access_value)
|
1449
|
+
raise_command_error("invalid access value: #{access_value}", optparse)
|
1418
1450
|
puts optparse
|
1419
1451
|
return 1
|
1420
1452
|
end
|
@@ -1484,44 +1516,49 @@ EOT
|
|
1484
1516
|
def update_persona_access(args)
|
1485
1517
|
options = {}
|
1486
1518
|
persona_id = nil
|
1519
|
+
name = nil
|
1487
1520
|
access_value = nil
|
1488
1521
|
do_all = false
|
1522
|
+
allowed_access_values = ['full', 'none']
|
1489
1523
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
1490
|
-
opts.banner = subcommand_usage("[
|
1524
|
+
opts.banner = subcommand_usage("[role] [persona] [access]")
|
1491
1525
|
opts.on( '--persona CODE', String, "Persona Code" ) do |val|
|
1492
1526
|
persona_id = val
|
1493
1527
|
end
|
1494
1528
|
opts.on( nil, '--all', "Update all personas at once." ) do
|
1495
1529
|
do_all = true
|
1496
1530
|
end
|
1497
|
-
opts.on( '--access VALUE', String, "Access value [
|
1531
|
+
opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
|
1498
1532
|
access_value = val
|
1499
1533
|
end
|
1500
1534
|
build_common_options(opts, options, [:json, :dry_run, :remote])
|
1501
|
-
opts.footer = "Update role access for
|
1502
|
-
"[
|
1503
|
-
"--persona or --all is required. This is the code of a persona
|
1504
|
-
"--access is required. This is the new access value."
|
1535
|
+
opts.footer = "Update role access for a persona or all personas.\n" +
|
1536
|
+
"[role] is required. This is the name or id of a role.\n" +
|
1537
|
+
"--persona or --all is required. This is the code of a persona. Service Catalog or Standard\n" +
|
1538
|
+
"--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
|
1505
1539
|
end
|
1506
1540
|
optparse.parse!(args)
|
1507
1541
|
|
1508
|
-
|
1509
|
-
|
1510
|
-
return 1
|
1511
|
-
end
|
1542
|
+
# usage: update-persona-access [role] [access] --all
|
1543
|
+
# update-persona-access [role] [persona] [access]
|
1512
1544
|
name = args[0]
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1545
|
+
if do_all
|
1546
|
+
verify_args!(args:args, optparse:optparse, min:1, max:2)
|
1547
|
+
access_value = args[1] if args[1]
|
1548
|
+
else
|
1549
|
+
verify_args!(args:args, optparse:optparse, min:1, max:3)
|
1550
|
+
persona_id = args[1] if args[1]
|
1551
|
+
access_value = args[2] if args[2]
|
1552
|
+
end
|
1553
|
+
if !persona_id && !do_all
|
1554
|
+
raise_command_error("missing required argument: [persona] or --all", optparse)
|
1555
|
+
end
|
1556
|
+
if !access_value
|
1557
|
+
raise_command_error("missing required argument: [access]", optparse)
|
1520
1558
|
end
|
1521
|
-
|
1522
1559
|
access_value = access_value.to_s.downcase
|
1523
|
-
|
1524
|
-
|
1560
|
+
if !allowed_access_values.include?(access_value)
|
1561
|
+
raise_command_error("invalid access value: #{access_value}", optparse)
|
1525
1562
|
puts optparse
|
1526
1563
|
return 1
|
1527
1564
|
end
|
@@ -1573,12 +1610,13 @@ EOT
|
|
1573
1610
|
|
1574
1611
|
def add_role_option_types
|
1575
1612
|
[
|
1576
|
-
{'fieldName' => 'authority', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true
|
1577
|
-
{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text'
|
1578
|
-
{'fieldName' => 'roleType', 'fieldLabel' => 'Role Type', 'type' => 'select', 'selectOptions' => [{'name' => 'User Role', 'value' => 'user'}, {'name' => 'Account Role', 'value' => 'account'}], 'defaultValue' => 'user'
|
1579
|
-
{'fieldName' => 'baseRole', 'fieldLabel' => 'Copy From Role', 'type' => 'text'
|
1580
|
-
{'fieldName' => 'multitenant', 'fieldLabel' => 'Multitenant', 'type' => 'checkbox', 'defaultValue' => 'off', 'description' => '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'
|
1581
|
-
{'fieldName' => 'multitenantLocked', 'fieldLabel' => 'Multitenant Locked', 'type' => 'checkbox', 'defaultValue' => 'off', 'description' => 'Prevents subtenants from branching off this role/modifying it. ',
|
1613
|
+
{'fieldName' => 'authority', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true},
|
1614
|
+
{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text'},
|
1615
|
+
{'fieldName' => 'roleType', 'fieldLabel' => 'Role Type', 'type' => 'select', 'selectOptions' => [{'name' => 'User Role', 'value' => 'user'}, {'name' => 'Account Role', 'value' => 'account'}], 'defaultValue' => 'user'},
|
1616
|
+
{'fieldName' => 'baseRole', 'fieldLabel' => 'Copy From Role', 'type' => 'text'},
|
1617
|
+
{'fieldName' => 'multitenant', 'fieldLabel' => 'Multitenant', 'type' => 'checkbox', 'defaultValue' => 'off', 'description' => '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'},
|
1618
|
+
{'fieldName' => 'multitenantLocked', 'fieldLabel' => 'Multitenant Locked', 'type' => 'checkbox', 'defaultValue' => 'off', 'description' => 'Prevents subtenants from branching off this role/modifying it. '},
|
1619
|
+
{'fieldName' => 'defaultPersona', 'fieldLabel' => 'Default Persona', 'type' => 'select', 'selectOptions' => [{'name'=>'Service Catalog','value'=>'serviceCatalog'},{'name'=>'Standard','value'=>'standard'}], 'description' => 'Default Persona'}
|
1582
1620
|
]
|
1583
1621
|
end
|
1584
1622
|
|