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.
@@ -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(update_option_type_option_types(), options[:options], @api_client)
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
- print_description_list({
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
- }, option_type)
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
@@ -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
- puts as_pretty_table([json_response], [
216
- {"Groups" => lambda {|it| get_access_string(it['globalSiteAccess']) } },
217
- {"Clouds" => lambda {|it| get_access_string(it['globalZoneAccess']) } },
218
- {"Instance Types" => lambda {|it| get_access_string(it['globalInstanceTypeAccess']) } },
219
- {"Blueprints" => lambda {|it| get_access_string(it['globalAppTemplateAccess'] || it['globalBlueprintAccess']) } },
220
- {"Catalog Item Types" => lambda {|it| get_access_string(it['globalCatalogItemTypeAccess']) } },
221
- ], options)
222
-
223
- #print_h2 "Group Access: #{get_access_string(json_response['globalSiteAccess'])}", options
224
- print cyan
225
- if json_response['globalSiteAccess'] == 'custom'
226
- print_h2 "Group Access", options
227
- if options[:include_group_access]
228
- rows = json_response['sites'].collect do |it|
229
- {
230
- name: it['name'],
231
- access: format_access_string(it['access'], ["none","read","full"]),
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 as_pretty_table(rows, [:name, :access], options)
249
+ print reset,"\n"
235
250
  else
236
- print cyan,"Use -g, --group-access to list custom access","\n"
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
- print cyan
245
- #puts "Cloud Access: #{get_access_string(json_response['globalZoneAccess'])}"
246
- #print "\n"
247
- if json_response['globalZoneAccess'] == 'custom'
248
- print_h2 "Cloud Access", options
249
- if options[:include_cloud_access]
250
- rows = json_response['zones'].collect do |it|
251
- {
252
- name: it['name'],
253
- access: format_access_string(it['access'], ["none","read","full"]),
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 as_pretty_table(rows, [:name, :access], options)
273
+ print reset,"\n"
257
274
  else
258
- print cyan,"Use -c, --cloud-access to list custom access","\n"
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 -b, --catalog-item-type-access to list custom access","\n"
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[:include_catalog_item_types_access]
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("[name] [options]")
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("[name]")
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("[name]")
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 [full|read|none]" ) do |val|
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
- "[name] is required. This is the name or id of a role.\n" +
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
- if (!group_name && !do_all) || !access_value
801
- puts optparse
802
- return 1
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
- if !['full', 'read', 'none'].include?(access_value)
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 [full|read|none]" ) do |val|
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
- "[name] is required. This is the name or id of a role.\n" +
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
- if args.count < 1
942
- puts optparse
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
- # support old usage: [name] [cloud] [access]
947
- cloud_name ||= args[1]
948
- access_value ||= args[2]
949
-
950
- if (!cloud_name && !do_all) || !access_value
951
- puts optparse
952
- return 1
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
- if !['full', 'none'].include?(access_value)
980
+ if !allowed_access_values.include?(access_value)
981
+ raise_command_error("invalid access value: #{access_value}", optparse)
959
982
  puts optparse
960
- exit 1
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 [name] [full|custom|none]"
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("[name] [full|custom|none]")
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("[name]")
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 [full|read|none]" ) do |val|
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
- "[name] is required. This is the name or id of a role.\n" +
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: [name] [instance-type] [access]
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 [name] [full|custom|none]"
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("[name] [full|custom|none]")
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("[name]")
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 [full|read|none]" ) do |val|
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
- "[name] is required. This is the name or id of a role.\n" +
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
- if args.count < 1
1245
- puts optparse
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
- # support old usage: [name] [blueprint] [access]
1250
- blueprint_id ||= args[1]
1251
- access_value ||= args[2]
1252
-
1253
- if (!blueprint_id && !do_all) || !access_value
1254
- puts_error optparse
1255
- return 1
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
- if !['full', 'none'].include?(access_value)
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 [name] [full|custom|none]"
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("[name] [full|custom|none]")
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("[name]")
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 [full|none]" ) do |val|
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
- "[name] is required. This is the name or id of a role.\n" +
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
- if args.count < 1
1402
- puts optparse
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
- # support old usage: [name] [catalog_item_type] [access]
1407
- catalog_item_type_id ||= args[1]
1408
- access_value ||= args[2]
1409
-
1410
- if (!catalog_item_type_id && !do_all) || !access_value
1411
- puts_error optparse
1412
- return 1
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
- if !['full', 'none'].include?(access_value)
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("[name] [serviceCatalog|standard]")
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 [full|none]" ) do |val|
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 an persona or personas.\n" +
1502
- "[name] is required. This is the name or id of a role.\n" +
1503
- "--persona or --all is required. This is the code of a persona.\n" +
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
- if args.count < 1
1509
- puts optparse
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
- # support old usage: [name] [persona] [access]
1514
- persona_id ||= args[1]
1515
- access_value ||= args[2]
1516
-
1517
- if (!persona_id && !do_all) || !access_value
1518
- puts_error optparse
1519
- return 1
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
- if !['full', 'none'].include?(access_value)
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, 'displayOrder' => 1},
1577
- {'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 2},
1578
- {'fieldName' => 'roleType', 'fieldLabel' => 'Role Type', 'type' => 'select', 'selectOptions' => [{'name' => 'User Role', 'value' => 'user'}, {'name' => 'Account Role', 'value' => 'account'}], 'defaultValue' => 'user', 'displayOrder' => 3},
1579
- {'fieldName' => 'baseRole', 'fieldLabel' => 'Copy From Role', 'type' => 'text', 'displayOrder' => 4},
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', 'displayOrder' => 5},
1581
- {'fieldName' => 'multitenantLocked', 'fieldLabel' => 'Multitenant Locked', 'type' => 'checkbox', 'defaultValue' => 'off', 'description' => 'Prevents subtenants from branching off this role/modifying it. ', 'displayOrder' => 6}
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