morpheus-cli 4.2.11 → 4.2.12

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c05a0d047f94e91857345c03ab934d64eef1b23620acf24b38057eba3d92cbcb
4
- data.tar.gz: 17a33813d17587e8686ef3ad1cbec018ef1e18049be40184aa76573d60eba469
3
+ metadata.gz: 5e122acdb8c77d80c4d352581e33ee8e8a7d7caf6e631fda4645e8f5854f8c6e
4
+ data.tar.gz: 67d82f25c0fd463098d96183f0301ee22f3538bd6d6043c77132ae12fa5c3324
5
5
  SHA512:
6
- metadata.gz: 8450675f6ce45f28e42b3919ac5e6c65f210fde6deb14671a78eef72b0b7d6f0d0d008a108fc0af56a45af3e4485788bd6d91697ab544e868974df73d9ea4c54
7
- data.tar.gz: b0f5a5f626de331115ca8863b8e60305ec66ba34bfd6762697778f084bf7553618e37613e755c4ddc8cea425d8241faece71bbcf6a2a9483b94a7b1c0712c495
6
+ metadata.gz: 84efcd68bc06c45125654bc2279894cb5e1d7ef484f63015185fdedbdcdef57c48179cababa63128fd978416109229e08dc267ee0094c74fb16824f4450a4306
7
+ data.tar.gz: 8326f9f6dc94b22cb3e0df8ce18155bbadf67e5256301d9ad0df07803c99e4eaccfe36eabcde0b8ec9461f226dd3beea5c0584c30bb5146937dbf70c59e7b75b
data/Dockerfile CHANGED
@@ -1,5 +1,5 @@
1
1
  FROM ruby:2.5.1
2
2
 
3
- RUN gem install morpheus-cli -v 4.2.11
3
+ RUN gem install morpheus-cli -v 4.2.12
4
4
 
5
5
  ENTRYPOINT ["morpheus"]
@@ -119,6 +119,10 @@ class Morpheus::Cli::InvoicesCommand
119
119
  opts.on('--raw-data', '--raw-data', "Display Raw Data, the cost data from the cloud provider's API.") do |val|
120
120
  options[:show_raw_data] = true
121
121
  end
122
+ opts.on('--totals', "View total costs and prices for all the invoices found.") do |val|
123
+ params['includeTotals'] = true
124
+ options[:show_invoice_totals] = true
125
+ end
122
126
  build_standard_list_options(opts, options)
123
127
  opts.footer = "List invoices."
124
128
  end
@@ -128,50 +132,48 @@ class Morpheus::Cli::InvoicesCommand
128
132
  if args.count > 0
129
133
  options[:phrase] = args.join(" ")
130
134
  end
131
- begin
132
- # construct params
133
- params.merge!(parse_list_options(options))
134
- if options[:clouds]
135
- cloud_ids = parse_cloud_id_list(options[:clouds])
136
- return 1, "clouds not found for #{options[:clouds]}" if cloud_ids.nil?
137
- params['zoneId'] = cloud_ids
138
- end
139
- if options[:groups]
140
- group_ids = parse_group_id_list(options[:groups])
141
- return 1, "groups not found for #{options[:groups]}" if group_ids.nil?
142
- params['siteId'] = group_ids
143
- end
144
- if options[:instances]
145
- instance_ids = parse_instance_id_list(options[:instances])
146
- return 1, "instances not found for #{options[:instances]}" if instance_ids.nil?
147
- params['instanceId'] = instance_ids
148
- end
149
- if options[:servers]
150
- server_ids = parse_server_id_list(options[:servers])
151
- return 1, "servers not found for #{options[:servers]}" if server_ids.nil?
152
- params['serverId'] = server_ids
153
- end
154
- if options[:users]
155
- user_ids = parse_user_id_list(options[:users])
156
- return 1, "users not found for #{options[:users]}" if user_ids.nil?
157
- params['userId'] = user_ids
158
- end
159
- if options[:projects]
160
- project_ids = parse_project_id_list(options[:projects])
161
- return 1, "projects not found for #{options[:projects]}" if project_ids.nil?
162
- params['projectId'] = project_ids
163
- end
164
- params['rawData'] = true if options[:show_raw_data]
165
- params['refId'] = ref_ids unless ref_ids.empty?
166
- @invoices_interface.setopts(options)
167
- if options[:dry_run]
168
- print_dry_run @invoices_interface.dry.list(params)
169
- return
170
- end
171
- json_response = @invoices_interface.list(params)
172
- render_result = render_with_format(json_response, options, 'invoices')
173
- return 0 if render_result
174
- invoices = json_response['invoices']
135
+ # construct params
136
+ params.merge!(parse_list_options(options))
137
+ if options[:clouds]
138
+ cloud_ids = parse_cloud_id_list(options[:clouds])
139
+ return 1, "clouds not found for #{options[:clouds]}" if cloud_ids.nil?
140
+ params['zoneId'] = cloud_ids
141
+ end
142
+ if options[:groups]
143
+ group_ids = parse_group_id_list(options[:groups])
144
+ return 1, "groups not found for #{options[:groups]}" if group_ids.nil?
145
+ params['siteId'] = group_ids
146
+ end
147
+ if options[:instances]
148
+ instance_ids = parse_instance_id_list(options[:instances])
149
+ return 1, "instances not found for #{options[:instances]}" if instance_ids.nil?
150
+ params['instanceId'] = instance_ids
151
+ end
152
+ if options[:servers]
153
+ server_ids = parse_server_id_list(options[:servers])
154
+ return 1, "servers not found for #{options[:servers]}" if server_ids.nil?
155
+ params['serverId'] = server_ids
156
+ end
157
+ if options[:users]
158
+ user_ids = parse_user_id_list(options[:users])
159
+ return 1, "users not found for #{options[:users]}" if user_ids.nil?
160
+ params['userId'] = user_ids
161
+ end
162
+ if options[:projects]
163
+ project_ids = parse_project_id_list(options[:projects])
164
+ return 1, "projects not found for #{options[:projects]}" if project_ids.nil?
165
+ params['projectId'] = project_ids
166
+ end
167
+ params['rawData'] = true if options[:show_raw_data]
168
+ params['refId'] = ref_ids unless ref_ids.empty?
169
+ @invoices_interface.setopts(options)
170
+ if options[:dry_run]
171
+ print_dry_run @invoices_interface.dry.list(params)
172
+ return
173
+ end
174
+ json_response = @invoices_interface.list(params)
175
+ invoices = json_response['invoices']
176
+ render_response(json_response, options, 'invoices') do
175
177
  title = "Morpheus Invoices"
176
178
  subtitles = []
177
179
  if params['startDate']
@@ -263,11 +265,35 @@ class Morpheus::Cli::InvoicesCommand
263
265
  end
264
266
  print as_pretty_table(invoices, columns, options)
265
267
  print_results_pagination(json_response, {:label => "invoice", :n_label => "invoices"})
268
+
269
+ if options[:show_invoice_totals]
270
+ invoice_totals = json_response['invoiceTotals']
271
+ if invoice_totals
272
+ print_h2 "Invoice Totals"
273
+ invoice_totals_columns = {
274
+ "# Invoices" => lambda {|it| format_number(json_response['meta']['total']) rescue '' },
275
+ "Total Price" => lambda {|it| format_money(it['actualTotalPrice']) },
276
+ "Total Cost" => lambda {|it| format_money(it['actualTotalCost']) },
277
+ "Running Price" => lambda {|it| format_money(it['actualRunningPrice']) },
278
+ "Running Cost" => lambda {|it| format_money(it['actualRunningCost']) },
279
+ # "Invoice Total Price" => lambda {|it| format_money(it['invoiceTotalPrice']) },
280
+ # "Invoice Total Cost" => lambda {|it| format_money(it['invoiceTotalCost']) },
281
+ # "Invoice Running Price" => lambda {|it| format_money(it['invoiceRunningPrice']) },
282
+ # "Invoice Running Cost" => lambda {|it| format_money(it['invoiceRunningCost']) },
283
+ # "Estimated Total Price" => lambda {|it| format_money(it['estimatedTotalPrice']) },
284
+ # "Estimated Total Cost" => lambda {|it| format_money(it['estimatedTotalCost']) },
285
+ # "Compute Price" => lambda {|it| format_money(it['computePrice']) },
286
+ # "Compute Cost" => lambda {|it| format_money(it['computeCost']) },
287
+ }
288
+ print_description_list(invoice_totals_columns, invoice_totals)
289
+ else
290
+ print "\n"
291
+ print yellow, "No invoice totals data", reset, "\n"
292
+ end
293
+ end
266
294
  end
267
295
  print reset,"\n"
268
- rescue RestClient::Exception => e
269
- print_rest_exception(e, options)
270
- return 1
296
+ return 0, nil
271
297
  end
272
298
  end
273
299
 
@@ -280,6 +306,7 @@ class Morpheus::Cli::InvoicesCommand
280
306
  # options[:show_costs] = true
281
307
  options[:show_prices] = true
282
308
  options[:show_raw_data] = true
309
+ options[:max_line_items] = 10000
283
310
  end
284
311
  opts.on('--estimates', '--estimates', "Display all estimated costs, from usage info: Compute, Memory, Storage, etc." ) do
285
312
  options[:show_estimates] = true
@@ -287,6 +314,13 @@ class Morpheus::Cli::InvoicesCommand
287
314
  opts.on('--raw-data', '--raw-data', "Display Raw Data, the cost data from the cloud provider's API.") do |val|
288
315
  options[:show_raw_data] = true
289
316
  end
317
+ opts.on('--pretty-raw-data', '--raw-data', "Display Raw Data that is a bit more pretty") do |val|
318
+ options[:show_raw_data] = true
319
+ options[:pretty_json] = true
320
+ end
321
+ opts.on('-m', '--max-line-items NUMBER', "Maximum number of line items to display. Default is 5.") do |val|
322
+ options[:max_line_items] = val.to_i
323
+ end
290
324
  opts.on('--no-line-items', '--no-line-items', "Do not display line items.") do |val|
291
325
  options[:hide_line_items] = true
292
326
  end
@@ -435,7 +469,7 @@ EOT
435
469
 
436
470
  if options[:show_raw_data]
437
471
  print_h2 "Raw Data"
438
- puts invoice['rawData']
472
+ puts as_json(invoice['rawData'], {pretty_json:false}.merge(options))
439
473
  end
440
474
 
441
475
  # Line Items
@@ -443,7 +477,7 @@ EOT
443
477
  if line_items && line_items.size > 0 && options[:hide_line_items] != true
444
478
 
445
479
  line_items_columns = [
446
- {"INVOICE ID" => lambda {|it| it['invoiceId'] } },
480
+ {"ID" => lambda {|it| it['id'] } },
447
481
  {"TYPE" => lambda {|it| format_invoice_ref_type(it) } },
448
482
  {"REF ID" => lambda {|it| it['refId'] } },
449
483
  {"REF NAME" => lambda {|it| it['refName'] } },
@@ -463,12 +497,14 @@ EOT
463
497
  ]
464
498
 
465
499
  if options[:show_raw_data]
466
- columns += [{"RAW DATA" => lambda {|it| truncate_string(it['rawData'].to_s, 10) } }]
500
+ line_items_columns += [{"RAW DATA" => lambda {|it| truncate_string(it['rawData'].to_s, 10) } }]
467
501
  end
468
502
 
469
503
  print_h2 "Line Items"
470
- print as_pretty_table(line_items, line_items_columns, options)
471
- print_results_pagination({total: line_items.size, size: line_items.size})
504
+ max_line_items = options[:max_line_items] ? options[:max_line_items].to_i : 5
505
+ paged_line_items = line_items.first(max_line_items)
506
+ print as_pretty_table(paged_line_items, line_items_columns, options)
507
+ print_results_pagination({total: line_items.size, size: paged_line_items.size}, {:label => "line item", :n_label => "line items"})
472
508
  end
473
509
 
474
510
  print reset,"\n"
@@ -577,6 +613,10 @@ EOT
577
613
  # opts.on('--prices', '--prices', "Display prices: Total, Compute, Memory, Storage, etc." ) do
578
614
  # options[:show_prices] = true
579
615
  # end
616
+ opts.on('--invoice-id ID', String, "Filter by Invoice ID") do |val|
617
+ params['invoiceId'] ||= []
618
+ params['invoiceId'] << val
619
+ end
580
620
  opts.on('--type TYPE', String, "Filter by Ref Type eg. ComputeSite (Group), ComputeZone (Cloud), ComputeServer (Host), Instance, Container, User") do |val|
581
621
  if val.to_s.downcase == 'cloud' || val.to_s.downcase == 'zone'
582
622
  params['refType'] = 'ComputeZone'
@@ -654,6 +694,10 @@ EOT
654
694
  opts.on('--raw-data', '--raw-data', "Display Raw Data, the cost data from the cloud provider's API.") do |val|
655
695
  options[:show_raw_data] = true
656
696
  end
697
+ opts.on('--totals', "View total costs and prices for all the invoices found.") do |val|
698
+ params['includeTotals'] = true
699
+ options[:show_invoice_totals] = true
700
+ end
657
701
  build_standard_list_options(opts, options)
658
702
  opts.footer = "List invoice line items."
659
703
  end
@@ -722,6 +766,7 @@ EOT
722
766
  # current_date = Time.now
723
767
  # current_period = "#{current_date.year}#{current_date.month.to_s.rjust(2, '0')}"
724
768
  columns = [
769
+ {"ID" => lambda {|it| it['id'] } },
725
770
  {"INVOICE ID" => lambda {|it| it['invoiceId'] } },
726
771
  {"TYPE" => lambda {|it| format_invoice_ref_type(it) } },
727
772
  {"REF ID" => lambda {|it| it['refId'] } },
@@ -744,8 +789,36 @@ EOT
744
789
  if options[:show_raw_data]
745
790
  columns += [{"RAW DATA" => lambda {|it| truncate_string(it['rawData'].to_s, 10) } }]
746
791
  end
792
+ if options[:show_invoice_totals]
793
+ line_item_totals = json_response['lineItemTotals']
794
+ if line_item_totals
795
+ totals_row = line_item_totals.clone
796
+ totals_row['id'] = 'TOTAL:'
797
+ #totals_row['usageCategory'] = 'TOTAL:'
798
+ line_items = line_items + [totals_row]
799
+ end
800
+ end
747
801
  print as_pretty_table(line_items, columns, options)
748
802
  print_results_pagination(json_response, {:label => "line item", :n_label => "line items"})
803
+
804
+ # if options[:show_invoice_totals]
805
+ # line_item_totals = json_response['lineItemTotals']
806
+ # if line_item_totals
807
+ # print_h2 "Line Items Totals"
808
+ # invoice_totals_columns = {
809
+ # "# Line Items" => lambda {|it| format_number(json_response['meta']['total']) rescue '' },
810
+ # "Cost" => lambda {|it| format_money(it['itemCost']) },
811
+ # "Price" => lambda {|it| format_money(it['itemPrice']) },
812
+ # "Tax" => lambda {|it| format_money(it['itemTax']) },
813
+ # "Usage" => lambda {|it| it['itemUsage'] },
814
+ # }
815
+ # print_description_list(invoice_totals_columns, line_item_totals)
816
+ # else
817
+ # print "\n"
818
+ # print yellow, "No line item totals data", reset, "\n"
819
+ # end
820
+ # end
821
+
749
822
  end
750
823
  print reset,"\n"
751
824
  end
@@ -763,6 +836,10 @@ EOT
763
836
  opts.on('--raw-data', '--raw-data', "Display Raw Data, the cost data from the cloud provider's API.") do |val|
764
837
  options[:show_raw_data] = true
765
838
  end
839
+ opts.on('--pretty-raw-data', '--raw-data', "Display Raw Data that is a bit more pretty") do |val|
840
+ options[:show_raw_data] = true
841
+ options[:pretty_json] = true
842
+ end
766
843
  build_standard_get_options(opts, options)
767
844
  opts.footer = "Get details about a specific invoice line item."
768
845
  opts.footer = <<-EOT
@@ -775,7 +852,7 @@ EOT
775
852
  connect(options)
776
853
  id_list = parse_id_list(args)
777
854
  return run_command_for_each_arg(id_list) do |arg|
778
- _get(arg, options)
855
+ _get_line_item(arg, options)
779
856
  end
780
857
  end
781
858
 
@@ -815,6 +892,12 @@ EOT
815
892
  "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
816
893
  }
817
894
  print_description_list(description_cols, line_item, options)
895
+
896
+ if options[:show_raw_data]
897
+ print_h2 "Raw Data"
898
+ puts as_json(line_item['rawData'], {pretty_json:false}.merge(options))
899
+ end
900
+
818
901
  print reset,"\n"
819
902
  end
820
903
  return 0, nil
@@ -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 ?
@@ -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)
@@ -698,7 +698,7 @@ EOT
698
698
  {'fieldName' => 'password', 'fieldLabel' => 'Password', 'type' => 'password', 'required' => true, 'displayOrder' => 5},
699
699
  {'fieldName' => 'passwordConfirmation', 'fieldLabel' => 'Confirm Password', 'type' => 'password', 'required' => true, 'displayOrder' => 6},
700
700
  {'fieldName' => 'role', 'fieldLabel' => 'Role', 'type' => 'text', 'description' => "Role names (comma separated)", 'displayOrder' => 7},
701
- {'fieldName' => 'receiveNotifications', 'fieldLabel' => 'receiveNotifications', 'type' => 'checkbox', 'required' => false, 'defaultValue' => true, 'displayOrder' => 58},
701
+ {'fieldName' => 'receiveNotifications', 'fieldLabel' => 'Receive Notifications?', 'type' => 'checkbox', 'required' => false, 'defaultValue' => true, 'displayOrder' => 58},
702
702
  {'fieldName' => 'linuxUsername', 'fieldLabel' => 'Linux Username', 'type' => 'text', 'required' => false, 'displayOrder' => 9},
703
703
  # {'fieldName' => 'linuxPassword', 'fieldLabel' => 'Linux Password', 'type' => 'password', 'required' => false, 'displayOrder' => 10},
704
704
  {'fieldName' => 'windowsUsername', 'fieldLabel' => 'Windows Username', 'type' => 'text', 'required' => false, 'displayOrder' => 11},
@@ -1,6 +1,6 @@
1
1
 
2
2
  module Morpheus
3
3
  module Cli
4
- VERSION = "4.2.11"
4
+ VERSION = "4.2.12"
5
5
  end
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: morpheus-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.11
4
+ version: 4.2.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Estes
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2020-05-08 00:00:00.000000000 Z
14
+ date: 2020-05-13 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler