morpheus-cli 5.0.2 → 5.2.0
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 +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
|
|