morpheus-cli 4.2.11 → 4.2.16

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.
@@ -550,10 +550,10 @@ module Morpheus::Cli::PrintHelper
550
550
  # label_width, justify = 0, "none"
551
551
  out = ""
552
552
  value = value.to_s
553
- if do_wrap && value && Morpheus::Cli::PrintHelper.terminal_width
553
+ if do_wrap && value && value.include?(" ") && Morpheus::Cli::PrintHelper.terminal_width
554
554
  value_width = Morpheus::Cli::PrintHelper.terminal_width - label_width
555
555
  if value_width > 0 && value.gsub(/\e\[(\d+)m/, '').to_s.size > value_width
556
- wrap_indent = label_width + 1 # plus 1 needs to go away
556
+ wrap_indent = label_width + 1
557
557
  value = wrap(value, value_width, wrap_indent)
558
558
  end
559
559
  end
@@ -571,7 +571,7 @@ module Morpheus::Cli::PrintHelper
571
571
  # truncate_string truncates a string and appends the suffix "..."
572
572
  # @param value [String] the string to pad
573
573
  # @param width [Integer] the length to truncate to
574
- # @param pad_char [String] the character to pad with. Default is ' '
574
+ # @param suffix [String] the character to pad right side with. Default is '...'
575
575
  def truncate_string(value, width, suffix="...")
576
576
  value = value.to_s
577
577
  # JD: hack alerty.. this sux, but it's a best effort to preserve values containing ascii coloring codes
@@ -603,6 +603,41 @@ module Morpheus::Cli::PrintHelper
603
603
  end
604
604
  end
605
605
 
606
+ # truncate_string truncates a string and appends the prefix "..."
607
+ # @param value [String] the string to pad
608
+ # @param width [Integer] the length to truncate to
609
+ # @param prefix [String] the character to pad left side with. Default is '...'
610
+ def truncate_string_right(value, width, prefix="...")
611
+ value = value.to_s
612
+ # JD: hack alerty.. this sux, but it's a best effort to preserve values containing ascii coloring codes
613
+ # it stops working when there are words separated by ascii codes, eg. two diff colors
614
+ # plus this is probably pretty slow...
615
+ uncolored_value = Term::ANSIColor.coloring? ? Term::ANSIColor.uncolored(value.to_s) : value.to_s
616
+ if uncolored_value != value
617
+ trimmed_value = nil
618
+ if uncolored_value.size > width
619
+ if prefix
620
+ trimmed_value = prefix + uncolored_value[(uncolored_value.size - width - prefix.size)..-1]
621
+ else
622
+ trimmed_value = uncolored_value[(uncolored_value.size - width)..-1]
623
+ end
624
+ return value.gsub(uncolored_value, trimmed_value)
625
+ else
626
+ return value
627
+ end
628
+ else
629
+ if value.size > width
630
+ if prefix
631
+ return prefix + value[(value.size - width - prefix.size)..-1]
632
+ else
633
+ return value[(value.size - width)..-1]
634
+ end
635
+ else
636
+ return value
637
+ end
638
+ end
639
+ end
640
+
606
641
  # justified returns a left, center, or right aligned string.
607
642
  # @param value [String] the string to pad
608
643
  # @param width [Integer] the length to truncate to
@@ -872,13 +907,7 @@ module Morpheus::Cli::PrintHelper
872
907
  out << color if color
873
908
  rows.each do |row|
874
909
  value = row[:value].to_s
875
- if do_wrap
876
- if value_width && value_width < value.size
877
- wrap_indent = label_width + 1
878
- value = wrap(value, value_width, wrap_indent)
879
- end
880
- end
881
- out << format_dt_dd(row[:label], value, label_width, justify) + "\n"
910
+ out << format_dt_dd(row[:label], value, label_width, justify, do_wrap) + "\n"
882
911
  end
883
912
  out << reset if color
884
913
  return out
@@ -259,6 +259,17 @@ module Morpheus::Cli::ProvisioningHelper
259
259
  end
260
260
  end
261
261
 
262
+ ## resources
263
+
264
+ # todo: crud and /api/options for resources
265
+
266
+ def parse_resource_id_list(id_list)
267
+ parse_id_list(id_list).collect do |resource_id|
268
+ #find_resource_by_name_or_id(resource_id)['id']
269
+ resource_id
270
+ end
271
+ end
272
+
262
273
  ## apps
263
274
 
264
275
  def find_app_by_id(id)
@@ -1697,7 +1708,7 @@ module Morpheus::Cli::ProvisioningHelper
1697
1708
  while add_another_metadata do
1698
1709
  field_context = "metadata#{metadata_index}"
1699
1710
  metadata = {}
1700
- metadata['id'] = nil
1711
+ #metadata['id'] = nil
1701
1712
  metadata_label = metadata_index == 0 ? "Metadata Tag" : "Metadata Tag [#{metadata_index+1}]"
1702
1713
  v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'name', 'type' => 'text', 'fieldLabel' => "#{metadata_label} Name", 'required' => true, 'description' => 'Metadata Tag Name.', 'defaultValue' => metadata['name']}], options[:options])
1703
1714
  # todo: metadata.type ?
@@ -47,7 +47,9 @@ module Morpheus
47
47
  end
48
48
  end
49
49
  # puts "Options Prompt #{options}"
50
- option_types.sort { |x,y| x['displayOrder'].to_i <=> y['displayOrder'].to_i }.each do |option_type|
50
+ # only sort if displayOrder is set
51
+ sorted_option_types = (option_types[0] && option_types[0]['displayOrder']) ? option_types.sort { |x,y| x['displayOrder'].to_i <=> y['displayOrder'].to_i } : option_types
52
+ sorted_option_types.each do |option_type|
51
53
  context_map = results
52
54
  value = nil
53
55
  value_found=false
@@ -71,17 +73,26 @@ module Morpheus
71
73
 
72
74
  # respect optionType.dependsOnCode
73
75
  if option_type['dependsOnCode'] && option_type['dependsOnCode'] != ""
74
- # optionTypes can have this setting in the format code=value or code:value
76
+ # support formats code=value or code:value OR code:(value|value2|value3)
75
77
  parts = option_type['dependsOnCode'].include?("=") ? option_type['dependsOnCode'].split("=") : option_type['dependsOnCode'].split(":")
76
78
  depends_on_code = parts[0]
77
- depends_on_value = parts[1]
79
+ depends_on_value = parts[1].to_s.strip
80
+ depends_on_values = []
81
+ if depends_on_value.size > 0
82
+ # strip parenthesis
83
+ if depends_on_value[0] && depends_on_value[0].chr == "("
84
+ depends_on_value = depends_on_value[1..-1]
85
+ end
86
+ depends_on_value.chomp(")")
87
+ depends_on_values = depends_on_value.split("|").collect { |it| it.strip }
88
+ end
78
89
  depends_on_option_type = option_types.find {|it| it["code"] == depends_on_code }
79
90
  # could not find the dependent option type, proceed and prompt
80
91
  if !depends_on_option_type.nil?
81
92
  # dependent option type has a different value
82
93
  depends_on_field_key = depends_on_option_type['fieldContext'] ? "#{depends_on_option_type['fieldContext']}.#{depends_on_option_type['fieldName']}" : "#{depends_on_option_type['fieldName']}"
83
94
  found_dep_value = get_object_value(results, depends_on_field_key) || get_object_value(options, depends_on_field_key)
84
- if depends_on_value && depends_on_value != found_dep_value
95
+ if depends_on_values.size > 0 && !depends_on_values.include?(found_dep_value)
85
96
  next
86
97
  end
87
98
  end
@@ -622,14 +633,28 @@ module Morpheus
622
633
  if source_type == "local"
623
634
  # prompt for content
624
635
  if file_params['content'].nil?
625
- file_params['content'] = multiline_prompt({'fieldContext' => full_field_key, 'fieldName' => 'content', 'type' => 'code-editor', 'fieldLabel' => 'Content', 'required' => true})
636
+ if options[:no_prompt]
637
+ print Term::ANSIColor.red, "\nMissing Required Option\n\n", Term::ANSIColor.reset
638
+ print Term::ANSIColor.red, " * Content [-O #{full_field_key}.content=] - File Content\n", Term::ANSIColor.reset
639
+ print "\n"
640
+ exit 1
641
+ else
642
+ file_params['content'] = multiline_prompt({'fieldContext' => full_field_key, 'fieldName' => 'content', 'type' => 'code-editor', 'fieldLabel' => 'Content', 'required' => true})
643
+ end
626
644
  end
627
645
  elsif source_type == "url"
628
646
  if file_params['url']
629
647
  file_params['contentPath'] = file_params.delete('url')
630
648
  end
631
649
  if file_params['contentPath'].nil?
632
- file_params['contentPath'] = generic_prompt({'fieldContext' => full_field_key, 'fieldName' => 'url', 'fieldLabel' => 'URL', 'type' => 'text', 'required' => true})
650
+ if options[:no_prompt]
651
+ print Term::ANSIColor.red, "\nMissing Required Option\n\n", Term::ANSIColor.reset
652
+ print Term::ANSIColor.red, " * URL [-O #{full_field_key}.url=] - Path of file in the repository\n", Term::ANSIColor.reset
653
+ print "\n"
654
+ exit 1
655
+ else
656
+ file_params['contentPath'] = generic_prompt({'fieldContext' => full_field_key, 'fieldName' => 'url', 'fieldLabel' => 'URL', 'type' => 'text', 'required' => true})
657
+ end
633
658
  end
634
659
  elsif source_type == "repository"
635
660
  if file_params['repository'].nil?
@@ -637,10 +662,21 @@ module Morpheus
637
662
  file_params['repository'] = {'id' => repository_id}
638
663
  end
639
664
  if file_params['contentPath'].nil?
640
- file_params['contentPath'] = generic_prompt({'fieldContext' => full_field_key, 'fieldName' => 'path', 'fieldLabel' => 'File Path', 'type' => 'text', 'required' => true})
665
+ if options[:no_prompt]
666
+ print Term::ANSIColor.red, "\nMissing Required Option\n\n", Term::ANSIColor.reset
667
+ print Term::ANSIColor.red, " * File Path [-O #{full_field_key}.path=] - Path of file in the repository\n", Term::ANSIColor.reset
668
+ print "\n"
669
+ exit 1
670
+ else
671
+ file_params['contentPath'] = generic_prompt({'fieldContext' => full_field_key, 'fieldName' => 'path', 'fieldLabel' => 'File Path', 'type' => 'text', 'required' => true})
672
+ end
641
673
  end
642
- if file_params['contentRef'].nil?
643
- file_params['contentRef'] = generic_prompt({'fieldContext' => full_field_key, 'fieldName' => 'ref', 'fieldLabel' => 'Version Ref', 'type' => 'text'})
674
+ if !file_params.key?('contentRef')
675
+ if options[:no_prompt]
676
+ # pass
677
+ else
678
+ file_params['contentRef'] = generic_prompt({'fieldContext' => full_field_key, 'fieldName' => 'ref', 'fieldLabel' => 'Version Ref', 'type' => 'text'})
679
+ end
644
680
  end
645
681
  end
646
682
  return file_params
@@ -461,7 +461,7 @@ class Morpheus::Cli::PriceSetsCommand
461
461
  private
462
462
 
463
463
  def currency_sym(currency)
464
- Money::Currency.new((currency || 'usd').to_sym).symbol
464
+ Money::Currency.new((currency.to_s != '' ? currency : 'usd').to_sym).symbol
465
465
  end
466
466
 
467
467
  def price_prefix(price)
@@ -7,11 +7,8 @@ class Morpheus::Cli::Projects
7
7
  # include Morpheus::Cli::InfrastructureHelper
8
8
  # include Morpheus::Cli::AccountsHelper
9
9
 
10
- register_subcommands :list, :get, :add, :update, :remove,
11
- # :add_tags, :remove_tags,
12
- #:add_instance, :remove_instance
13
- #:add_host, :remove_host
14
-
10
+ register_subcommands :list, :get, :add, :update, :remove
11
+
15
12
  def connect(opts)
16
13
  @api_client = establish_remote_appliance_connection(opts)
17
14
  @projects_interface = @api_client.projects
@@ -27,7 +24,7 @@ class Morpheus::Cli::Projects
27
24
  def list(args)
28
25
  params = {}
29
26
  options = {}
30
- instance_ids, server_ids, cloud_ids = nil, nil, nil
27
+ instance_ids, server_ids, cloud_ids, resource_ids, owner_ids = nil, nil, nil, nil, nil
31
28
  optparse = Morpheus::Cli::OptionParser.new do |opts|
32
29
  opts.banner = subcommand_usage()
33
30
  opts.on('--instances [LIST]', Array, "Filter by Instance, comma separated list of instance names or IDs.") do |list|
@@ -39,9 +36,12 @@ class Morpheus::Cli::Projects
39
36
  opts.on('--clouds [LIST]', Array, "Filter by Cloud, comma separated list of cloud (zone) names or IDs.") do |list|
40
37
  cloud_ids = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
41
38
  end
42
- # opts.on('--owner [LIST]', Array, "Owner, comma separated list of usernames or IDs.") do |list|
43
- # params['ownerId'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
44
- # end
39
+ opts.on('--resources [LIST]', Array, "Filter by Resources, comma separated list of resource IDs.") do |list|
40
+ resource_ids = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
41
+ end
42
+ opts.on('--owners [LIST]', Array, "Owner, comma separated list of usernames or IDs.") do |list|
43
+ owner_ids = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
44
+ end
45
45
  build_standard_get_options(opts, options)
46
46
  opts.footer = <<-EOT
47
47
  List projects.
@@ -56,6 +56,8 @@ EOT
56
56
  # todo server and cloud, missing parse_server_id_list() too
57
57
  params['serverId'] = parse_server_id_list(server_ids) if server_ids
58
58
  params['cloudId'] = parse_cloud_id_list(cloud_ids) if cloud_ids
59
+ params['resourceId'] = parse_resource_id_list(resource_ids) if resource_ids
60
+ params['ownerId'] = parse_user_id_list(owner_ids) if owner_ids
59
61
  @projects_interface.setopts(options)
60
62
  if options[:dry_run]
61
63
  print_dry_run @projects_interface.dry.list(params)
@@ -79,6 +81,7 @@ EOT
79
81
  {"INSTANCES" => lambda {|it| it['instances'].size rescue '' } },
80
82
  {"SERVERS" => lambda {|it| it['servers'].size rescue '' } },
81
83
  {"CLOUDS" => lambda {|it| it['clouds'].size rescue '' } },
84
+ {"RESOURCES" => lambda {|it| it['resources'].size rescue '' } },
82
85
  {"OWNER" => lambda {|it| it['owner'] ? it['owner']['username'] : '' } },
83
86
  {"DATE CREATED" => lambda {|it| format_local_dt(it['dateCreated']) } },
84
87
  {"LAST UPDATED" => lambda {|it| format_local_dt(it['lastUpdated']) } },
@@ -98,10 +101,7 @@ EOT
98
101
  def get(args)
99
102
  options = {}
100
103
  optparse = Morpheus::Cli::OptionParser.new do |opts|
101
- opts.banner = subcommand_usage("[workflow]")
102
- opts.on('--no-content', "Do not display script content." ) do
103
- options[:no_content] = true
104
- end
104
+ opts.banner = subcommand_usage("[project]")
105
105
  build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
106
106
  opts.footer = <<-EOT
107
107
  Get details about a project.
@@ -169,6 +169,14 @@ EOT
169
169
  print cyan
170
170
  print as_pretty_table(project_clouds, [:id, :name], options)
171
171
  end
172
+
173
+ project_resources = project["resources"] || project["accountResources"]
174
+ if project_resources && project_resources.size > 0
175
+ print_h2 "Resources"
176
+ print cyan
177
+ print as_pretty_table(project_resources, [:id, :name], options)
178
+ end
179
+
172
180
  print reset,"\n"
173
181
  end
174
182
  return 0, nil
@@ -177,7 +185,7 @@ EOT
177
185
  def add(args)
178
186
  exit_code, err = 0, nil
179
187
  params, options, payload = {}, {}, {}
180
- project_name, description, metadata, instance_ids, server_ids, cloud_ids = nil, nil, nil, nil, nil, nil
188
+ project_name, description, metadata, instance_ids, server_ids, cloud_ids, resource_ids = nil, nil, nil, nil, nil, nil, nil
181
189
  optparse = Morpheus::Cli::OptionParser.new do |opts|
182
190
  opts.banner = subcommand_usage("[name]")
183
191
  opts.on('--name NAME', String, "Project Name" ) do |val|
@@ -198,6 +206,9 @@ EOT
198
206
  opts.on('--clouds [LIST]', Array, "Clouds, comma separated list of cloud names or IDs.") do |list|
199
207
  cloud_ids = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
200
208
  end
209
+ opts.on('--resources [LIST]', Array, "Resources, comma separated list of resource IDs.") do |list|
210
+ resource_ids = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
211
+ end
201
212
  build_standard_add_options(opts, options)
202
213
  opts.footer = <<-EOT
203
214
  Create a project.
@@ -228,11 +239,6 @@ EOT
228
239
  metadata = prompt_metadata(options)
229
240
  payload['project']['tags'] = metadata if metadata
230
241
  end
231
- if instance_ids != nil
232
- payload['project']['instances'] = parse_instance_id_list(instance_ids).collect { |it| {'id': it.to_i} }
233
- else
234
- # could prompt
235
- end
236
242
  # --instances
237
243
  if instance_ids
238
244
  payload['project']['instances'] = parse_instance_id_list(instance_ids).collect { |it| {'id': it.to_i} }
@@ -245,6 +251,10 @@ EOT
245
251
  if cloud_ids
246
252
  payload['project']['clouds'] = parse_cloud_id_list(cloud_ids).collect { |it| {'id': it.to_i} }
247
253
  end
254
+ # --resources
255
+ if resource_ids
256
+ payload['project']['resources'] = parse_resource_id_list(resource_ids).collect { |it| {'id': it.to_i} }
257
+ end
248
258
  end
249
259
  @projects_interface.setopts(options)
250
260
  if options[:dry_run]
@@ -264,10 +274,11 @@ EOT
264
274
  exit_code, err = 0, nil
265
275
  params, options, payload = {}, {}, {}
266
276
  project_name, description, metadata, add_metadata, remove_metadata = nil, nil, nil, nil, nil
267
- instance_ids, server_ids, cloud_ids = nil, nil, nil
277
+ instance_ids, server_ids, cloud_ids, resource_ids = nil, nil, nil, nil
268
278
  add_instance_ids, remove_instance_ids = nil, nil
269
279
  add_server_ids, remove_server_ids = nil, nil
270
280
  add_cloud_ids, remove_cloud_ids = nil, nil
281
+ add_resource_ids, remove_resource_ids = nil, nil
271
282
  optparse = Morpheus::Cli::OptionParser.new do |opts|
272
283
  opts.banner = subcommand_usage("[project] [options]")
273
284
  opts.on('--name NAME', String, "Project Name" ) do |val|
@@ -312,6 +323,15 @@ EOT
312
323
  opts.on('--remove-clouds LIST', Array, "Remove Clouds, comma separated list of cloud names or IDs to remove.") do |list|
313
324
  remove_cloud_ids = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
314
325
  end
326
+ opts.on('--resources [LIST]', Array, "Resources, comma separated list of resource names or IDs.") do |list|
327
+ resource_ids = list ? list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq : []
328
+ end
329
+ opts.on('--add-resources LIST', Array, "Add Resources, comma separated list of resource names or IDs to add.") do |list|
330
+ add_resource_ids = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
331
+ end
332
+ opts.on('--remove-resources LIST', Array, "Remove Resources, comma separated list of resource names or IDs to remove.") do |list|
333
+ remove_resource_ids = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
334
+ end
315
335
  build_standard_update_options(opts, options)
316
336
  opts.footer = <<-EOT
317
337
  Update a project.
@@ -379,109 +399,19 @@ EOT
379
399
  return 1, "clouds not found" if remove_cloud_ids.nil?
380
400
  payload['project']['removeClouds'] = remove_cloud_ids.collect { |it| {'id': it.to_i} }
381
401
  end
382
- end
383
- @projects_interface.setopts(options)
384
- if options[:dry_run]
385
- print_dry_run @projects_interface.dry.update(project['id'], payload)
386
- return
387
- end
388
- json_response = @projects_interface.update(project['id'], payload)
389
- project = json_response['project']
390
- render_response(json_response, options, 'project') do
391
- print_green_success "Project #{project['name']} updated"
392
- exit_code, err = get([project['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
393
- end
394
- return exit_code, err
395
- end
396
-
397
- def add_tags(args)
398
- params = {}
399
- options = {}
400
- payload = {}
401
- metadata = nil
402
- optparse = Morpheus::Cli::OptionParser.new do |opts|
403
- opts.banner = subcommand_usage("[project] [tag=value] [tag=value]")
404
- opts.on('--tags TAGS', String, "Project Tags in the format 'name:value, name:value'. This will add/update project tags.") do |val|
405
- metadata = val
402
+ # --resources
403
+ if resource_ids
404
+ payload['project']['resources'] = parse_resource_id_list(resource_ids).collect { |it| {'id': it.to_i} }
406
405
  end
407
- build_standard_update_options(opts, options)
408
- opts.footer = <<-EOT
409
- Add metadata tags to a project.
410
- [project] is required. This is the name or id of a project.
411
- [tag=value] is required. This is a metadata tag in the format name=value, 1-N may be passed.
412
- EOT
413
- end
414
- optparse.parse!(args)
415
- verify_args!(args:args, optparse:optparse, min:1) # maybe min:2 instead ?
416
- connect(options)
417
- exit_code, err = 0, nil
418
- if args.count > 1
419
- metadata = args[1..-1].join(" ")
420
- end
421
- project = find_project_by_name_or_id(args[0])
422
- return 1, "project not found by '#{args[0]}'" if project.nil?
423
- # construct payload
424
-
425
- if options[:payload]
426
- payload = options[:payload]
427
- payload.deep_merge!({'project' => parse_passed_options(options)})
428
- else
429
- payload['project'] = {}
430
- payload.deep_merge!({'project' => parse_passed_options(options)})
431
- if options[:metadata]
432
- payload['project']['addTags'] = parse_metadata(metadata)
433
- end
434
- end
435
- @projects_interface.setopts(options)
436
- if options[:dry_run]
437
- print_dry_run @projects_interface.dry.update(project['id'], payload)
438
- return
439
- end
440
- json_response = @projects_interface.update(project['id'], payload)
441
- project = json_response['project']
442
- render_response(json_response, options, 'project') do
443
- print_green_success "Project #{project['name']} updated"
444
- exit_code, err = get([project['id']] + (options[:remote] ? ["-r",options[:remote]] : []))
445
- end
446
- return exit_code, err
447
- end
448
-
449
- def remove_tags(args)
450
- params = {}
451
- options = {}
452
- payload = {}
453
- metadata = nil
454
- optparse = Morpheus::Cli::OptionParser.new do |opts|
455
- opts.banner = subcommand_usage("[project] [tags]")
456
- opts.on('--tags TAGS', String, "Project Tags in the format 'name=value, name=value'. This will add/update project tags.") do |val|
457
- metadata = val
406
+ if add_resource_ids
407
+ add_resource_ids = parse_resource_id_list(add_resource_ids)
408
+ return 1, "resources not found" if add_resource_ids.nil?
409
+ payload['project']['addResources'] = add_resource_ids.collect { |it| {'id': it.to_i} }
458
410
  end
459
- build_standard_update_options(opts, options)
460
- opts.footer = <<-EOT
461
- Remove metadata tags from a project.
462
- [project] is required. This is the name or id of a project.
463
- [tags] is required. This is a metadata tag in the format tag=value, tag2, tag3, 1-N may be passed, value is optional and must match if passed.
464
- EOT
465
- end
466
- optparse.parse!(args)
467
- verify_args!(args:args, optparse:optparse, min:1) # maybe min:2 instead ?
468
- connect(options)
469
- exit_code, err = 0, nil
470
- if args.count > 1
471
- metadata = args[1..-1].join(" ")
472
- end
473
- project = find_project_by_name_or_id(args[0])
474
- return 1, "project not found by '#{args[0]}'" if project.nil?
475
- # construct payload
476
-
477
- if options[:payload]
478
- payload = options[:payload]
479
- payload.deep_merge!({'project' => parse_passed_options(options)})
480
- else
481
- payload['project'] = {}
482
- payload.deep_merge!({'project' => parse_passed_options(options)})
483
- if metadata
484
- payload['project']['removeTags'] = parse_metadata(metadata)
411
+ if remove_resource_ids
412
+ remove_resource_ids = parse_resource_id_list(remove_resource_ids)
413
+ return 1, "resources not found" if remove_resource_ids.nil?
414
+ payload['project']['removeResources'] = remove_resource_ids.collect { |it| {'id': it.to_i} }
485
415
  end
486
416
  end
487
417
  @projects_interface.setopts(options)