morpheus-cli 4.2.22 → 5.0.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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/lib/morpheus/api/api_client.rb +14 -0
  4. data/lib/morpheus/api/billing_interface.rb +33 -0
  5. data/lib/morpheus/api/catalog_item_types_interface.rb +9 -0
  6. data/lib/morpheus/api/rest_interface.rb +0 -6
  7. data/lib/morpheus/api/roles_interface.rb +14 -0
  8. data/lib/morpheus/cli.rb +2 -2
  9. data/lib/morpheus/cli/apps.rb +3 -4
  10. data/lib/morpheus/cli/backup_jobs_command.rb +3 -0
  11. data/lib/morpheus/cli/backups_command.rb +3 -0
  12. data/lib/morpheus/cli/catalog_command.rb +507 -0
  13. data/lib/morpheus/cli/cli_command.rb +19 -11
  14. data/lib/morpheus/cli/commands/standard/source_command.rb +1 -1
  15. data/lib/morpheus/cli/commands/standard/update_command.rb +76 -0
  16. data/lib/morpheus/cli/containers_command.rb +14 -0
  17. data/lib/morpheus/cli/hosts.rb +30 -2
  18. data/lib/morpheus/cli/instances.rb +19 -1
  19. data/lib/morpheus/cli/library_option_lists_command.rb +14 -6
  20. data/lib/morpheus/cli/mixins/accounts_helper.rb +7 -6
  21. data/lib/morpheus/cli/mixins/backups_helper.rb +2 -4
  22. data/lib/morpheus/cli/mixins/catalog_helper.rb +66 -0
  23. data/lib/morpheus/cli/mixins/deployments_helper.rb +0 -1
  24. data/lib/morpheus/cli/mixins/option_source_helper.rb +1 -1
  25. data/lib/morpheus/cli/mixins/print_helper.rb +46 -0
  26. data/lib/morpheus/cli/ping.rb +0 -1
  27. data/lib/morpheus/cli/remote.rb +0 -2
  28. data/lib/morpheus/cli/roles.rb +305 -3
  29. data/lib/morpheus/cli/storage_providers_command.rb +40 -56
  30. data/lib/morpheus/cli/usage_command.rb +150 -0
  31. data/lib/morpheus/cli/user_settings_command.rb +1 -0
  32. data/lib/morpheus/cli/users.rb +12 -1
  33. data/lib/morpheus/cli/version.rb +1 -1
  34. data/lib/morpheus/formatters.rb +26 -5
  35. metadata +8 -2
@@ -42,71 +42,39 @@ class Morpheus::Cli::StorageProvidersCommand
42
42
  def list(args)
43
43
  options = {}
44
44
  params = {}
45
+ ref_ids = []
45
46
  optparse = Morpheus::Cli::OptionParser.new do |opts|
46
- opts.banner = subcommand_usage()
47
- build_common_options(opts, options, [:list, :json, :yaml, :csv, :fields, :json, :dry_run, :remote])
47
+ opts.banner = subcommand_usage("[search]")
48
+ build_standard_list_options(opts, options)
48
49
  opts.footer = "List storage buckets."
49
50
  end
50
51
  optparse.parse!(args)
51
- if args.count != 0
52
- print_error Morpheus::Terminal.angry_prompt
53
- puts_error "wrong number of arguments, expected 0 and got #{args.count}\n#{optparse}"
54
- return 1
55
- end
56
52
  connect(options)
57
- begin
58
- params.merge!(parse_list_options(options))
59
- @storage_providers_interface.setopts(options)
60
- if options[:dry_run]
61
- print_dry_run @storage_providers_interface.dry.list(params)
62
- return
63
- end
64
- json_response = @storage_providers_interface.list(params)
65
- storage_providers = json_response["storageBuckets"]
66
- if options[:json]
67
- puts as_json(json_response, options, "storageBuckets")
68
- return 0
69
- elsif options[:yaml]
70
- puts as_yaml(json_response, options, "storageBuckets")
71
- return 0
72
- elsif options[:csv]
73
- puts records_as_csv(storage_providers, options)
74
- return 0
75
- end
76
- title = "Morpheus Storage Buckets"
77
- subtitles = []
78
- subtitles += parse_list_subtitles(options)
79
- print_h1 title, subtitles
80
- if storage_providers.empty?
53
+ if args.count > 0
54
+ options[:phrase] = args.join(" ")
55
+ end
56
+ params.merge!(parse_list_options(options))
57
+ @storage_providers_interface.setopts(options)
58
+ if options[:dry_run]
59
+ print_dry_run @storage_providers_interface.dry.list(params)
60
+ return
61
+ end
62
+ json_response = @storage_providers_interface.list(params)
63
+ storage_buckets = json_response['storageBuckets']
64
+ render_response(json_response, options, 'storageBuckets') do
65
+ print_h1 "Morpheus Storage Buckets", parse_list_subtitles(options), options
66
+ if storage_buckets.empty?
81
67
  print cyan,"No storage buckets found.",reset,"\n"
82
68
  else
83
- rows = storage_providers.collect {|storage_provider|
84
- row = {
85
- id: storage_provider['id'],
86
- name: storage_provider['name'],
87
- provider: format_storage_provider_type(storage_provider),
88
- bucket: format_bucket_name(storage_provider),
89
- backups: storage_provider['defaultBackupTarget'] ? 'Yes' : 'No',
90
- deployments: storage_provider['defaultDeploymentTarget'] ? 'Yes' : 'No',
91
- virtualImages: storage_provider['defaultVirtualImageTarget'] ? 'Yes' : 'No',
92
- }
93
- row
94
- }
95
- columns = [:id, :name, {:provider => {:display_name => "Provider Type".upcase} }, {:bucket => {:display_name => "Bucket Name".upcase} }, :backups, :deployments]
96
- if options[:include_fields]
97
- columns = options[:include_fields]
98
- rows = storage_providers
99
- end
100
- print cyan
101
- print as_pretty_table(rows, columns, options)
102
- print reset
103
- print_results_pagination(json_response, {:label => "storage bucket", :n_label => "storage buckets"})
69
+ print as_pretty_table(storage_buckets, storage_bucket_column_definitions.upcase_keys!, options)
70
+ print_results_pagination(json_response)
104
71
  end
105
72
  print reset,"\n"
106
- return 0
107
- rescue RestClient::Exception => e
108
- print_rest_exception(e, options)
109
- exit 1
73
+ end
74
+ if storage_buckets.empty?
75
+ return 1, "no storage buckets found"
76
+ else
77
+ return 0, nil
110
78
  end
111
79
  end
112
80
 
@@ -1232,6 +1200,22 @@ class Morpheus::Cli::StorageProvidersCommand
1232
1200
 
1233
1201
  private
1234
1202
 
1203
+ def storage_bucket_column_definitions()
1204
+ {
1205
+ "ID" => 'id',
1206
+ "Name" => 'name',
1207
+ # "Description" => 'description',
1208
+ "Provider Type" => lambda {|it| format_storage_provider_type(it) },
1209
+ "Bucket Name" => lambda {|it| format_bucket_name(it) },
1210
+ # "Source" => lambda {|it| it['source'] },
1211
+ "Backups" => lambda {|it| format_boolean(it['defaultBackupTarget']) },
1212
+ "Deployments" => lambda {|it| format_boolean(it['defaultDeploymentTarget']) },
1213
+ "Virtual Images" => lambda {|it| format_boolean(it['defaultVirtualImageTarget']) },
1214
+ # "Archive Snapshots" => lambda {|it| format_boolean(it['copyToStore']) },
1215
+ # "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
1216
+ # "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
1217
+ }
1218
+ end
1235
1219
 
1236
1220
  def get_storage_provider_types()
1237
1221
  [
@@ -0,0 +1,150 @@
1
+ require 'morpheus/cli/cli_command'
2
+
3
+ # CLI command usages
4
+ # UI is Costing - Usage
5
+ # API is /billing and returns usages
6
+ class Morpheus::Cli::UsageCommand
7
+ include Morpheus::Cli::CliCommand
8
+ include Morpheus::Cli::OptionSourceHelper
9
+
10
+ set_command_name :'usage'
11
+
12
+ register_subcommands :list #, :list_tenant, :list_clouds, :list_zones, :list_zones, :list_zones, :list_zones
13
+
14
+ def connect(opts)
15
+ @api_client = establish_remote_appliance_connection(opts)
16
+ @billing_interface = @api_client.billing
17
+ end
18
+
19
+ def handle(args)
20
+ handle_subcommand(args)
21
+ end
22
+
23
+ def list(args)
24
+ options = {}
25
+ params = {}
26
+ ref_ids = []
27
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
28
+ opts.banner = subcommand_usage("[search]")
29
+ opts.on( '-t', '--type TYPE', "Filter by type" ) do |val|
30
+ params['type'] = parse_usage_type(val)
31
+ end
32
+ opts.on( '-c', '--cloud CLOUD', "Filter by cloud" ) do |val|
33
+ options[:cloud] = val
34
+ end
35
+ opts.on('--start DATE', String, "Start date in the format YYYY-MM-DD.") do |val|
36
+ params['startDate'] = val #parse_time(val).utc.iso8601
37
+ end
38
+ opts.on('--end DATE', String, "End date in the format YYYY-MM-DD. Default is now.") do |val|
39
+ params['endDate'] = val #parse_time(val).utc.iso8601
40
+ end
41
+ opts.on('--sigdig DIGITS', "Significant digits when rounding cost values for display as currency. Default is 5.") do |val|
42
+ options[:sigdig] = val.to_i
43
+ end
44
+ build_standard_list_options(opts, options)
45
+ opts.footer = "List usages."
46
+ end
47
+ optparse.parse!(args)
48
+ connect(options)
49
+ # verify_args!(args:args, optparse:optparse, count:0)
50
+ if args.count > 0
51
+ options[:phrase] = args.join(" ")
52
+ end
53
+ params.merge!(parse_list_options(options))
54
+ # --cloud
55
+ if options[:cloud]
56
+ params['cloud'] = parse_id_list(options[:cloud]).collect {|cloud_id|
57
+ if cloud_id.to_s =~ /\A\d{1,}\Z/
58
+ cloud_id
59
+ else
60
+ cloud = find_cloud_option(cloud_id)
61
+ return 1 if cloud.nil?
62
+ cloud['id']
63
+ end
64
+ }
65
+ end
66
+
67
+ @billing_interface.setopts(options)
68
+ if options[:dry_run]
69
+ print_dry_run @billing_interface.dry.list(params)
70
+ return
71
+ end
72
+ json_response = @billing_interface.list(params)
73
+ usages = json_response[usage_list_key]
74
+ render_response(json_response, options, usage_list_key) do
75
+ print_h1 "Morpheus Usages", parse_list_subtitles(options), options
76
+ if usages.empty?
77
+ print cyan,"No usages found.",reset,"\n"
78
+ else
79
+ list_columns = {
80
+ "ID" => 'id',
81
+ "Cloud" => 'zoneName',
82
+ "Type" => lambda {|it| format_usage_type(it) },
83
+ "Name" => 'name',
84
+ "Plan" => 'planName',
85
+ "Start Date" => lambda {|it| format_local_dt(it['startDate']) },
86
+ "End Date" => lambda {|it| format_local_dt(it['endDate']) },
87
+ "Usage Status" => lambda {|it| format_usage_status(it) },
88
+ "Usage Price" => lambda {|it| format_money(it['price'], it['currency'] || 'USD', {sigdig: (options[:sigdig] || 5)}) },
89
+ }
90
+ print as_pretty_table(usages, list_columns.upcase_keys!, options)
91
+ print_results_pagination(json_response)
92
+ end
93
+ print reset,"\n"
94
+ end
95
+ if usages.empty?
96
+ return 1, "no usages found"
97
+ else
98
+ return 0, nil
99
+ end
100
+ end
101
+
102
+
103
+ private
104
+
105
+ def usage_object_key
106
+ 'usage'
107
+ end
108
+
109
+ def usage_list_key
110
+ 'usages'
111
+ end
112
+
113
+ def format_usage_type(usage)
114
+ #return usage['costDetails']['refType']
115
+ ref_type = usage['costDetails'] ? usage['costDetails']['refType'].to_s : ''
116
+ if ref_type == 'discoveredServer'
117
+ 'Discovered'
118
+ elsif ref_type == 'computeServer'
119
+ 'Host'
120
+ elsif ref_type == 'container'
121
+ 'Container'
122
+ else
123
+ ref_type.to_s
124
+ end
125
+ end
126
+
127
+ def parse_usage_type(val)
128
+ type_string = val.to_s.downcase
129
+ if type_string == 'discoveredServer'
130
+ 'discoveredServer'
131
+ elsif type_string == 'host'
132
+ 'computeServer'
133
+ elsif type_string == 'container'
134
+ 'container'
135
+ else
136
+ val
137
+ end
138
+ end
139
+
140
+ def format_usage_status(usage, return_color=cyan)
141
+ #return usage['status'].to_s.capitalize
142
+ status_string = usage['status'].to_s
143
+ if status_string == 'stopped'
144
+ return "#{cyan}#{status_string.upcase}#{return_color}"
145
+ else
146
+ return "#{cyan}#{status_string.upcase}#{return_color}"
147
+ end
148
+ end
149
+
150
+ end
@@ -94,6 +94,7 @@ EOT
94
94
  "Linux Key Pair" => lambda {|it| it['linuxKeyPairId'] },
95
95
  "Windows Username" => lambda {|it| it['windowsUsername'] },
96
96
  "Windows Password" => lambda {|it| it['windowsPassword'] },
97
+ "Default Persona" => lambda {|it| it['defaultPersona'] ? it['defaultPersona']['name'] : '' },
97
98
  }
98
99
  print_description_list(description_cols, user_settings)
99
100
 
@@ -161,12 +161,22 @@ class Morpheus::Cli::Users
161
161
  options[:include_app_templates_access] = true
162
162
  params['includeAccess'] = true
163
163
  end
164
+ opts.on(nil,'--catalog-item-type-access', "Display Catalog Item Type Access") do
165
+ options[:include_catalog_item_types_access] = true
166
+ params['includeAccess'] = true
167
+ end
168
+ opts.on(nil,'--personas', "Display Persona Access") do
169
+ options[:include_personas_access] = true
170
+ params['includeAccess'] = true
171
+ end
164
172
  opts.on(nil,'--all', "Display All Access Lists") do
165
173
  options[:include_features_access] = true
166
174
  options[:include_sites_access] = true
167
175
  options[:include_zones_access] = true
168
176
  options[:include_instance_types_access] = true
169
177
  options[:include_app_templates_access] = true
178
+ options[:include_catalog_item_types_access] = true
179
+ options[:include_personas_access] = true
170
180
  params['includeAccess'] = true
171
181
  end
172
182
  opts.on('-i', '--include-none-access', "Include Items with 'None' Access in Access List") do
@@ -241,7 +251,8 @@ EOT
241
251
  puts yellow,"No permissions found.",reset
242
252
  end
243
253
  else
244
- available_field_options = {'features' => 'Feature', 'sites' => 'Group', 'zones' => 'Cloud', 'instance_types' => 'Instance Type', 'app_templates' => 'Blueprint'}
254
+ available_field_options = {'features' => 'Feature', 'sites' => 'Group', 'zones' => 'Cloud', 'instance_types' => 'Instance Type',
255
+ 'app_templates' => 'Blueprint', 'catalog_item_types' => 'Catalog Item Types', 'personas' => 'Personas'}
245
256
  available_field_options.each do |field, label|
246
257
  if !(field == 'sites' && is_tenant_account) && options["include_#{field}_access".to_sym]
247
258
  access = user['access'][field.split('_').enum_for(:each_with_index).collect {|word, idx| idx == 0 ? word : word.capitalize}.join]
@@ -1,6 +1,6 @@
1
1
 
2
2
  module Morpheus
3
3
  module Cli
4
- VERSION = "4.2.22"
4
+ VERSION = "5.0.0"
5
5
  end
6
6
  end
@@ -365,8 +365,21 @@ def format_number(n, opts={})
365
365
  return out
366
366
  end
367
367
 
368
- def format_sig_dig(n, sigdig=3)
369
- sprintf("%.#{sigdig}f", n)
368
+ def format_sig_dig(n, sigdig=3, min_sigdig=nil, pad_zeros=false)
369
+ v = sprintf("%.#{sigdig}f", n)
370
+ if pad_zeros != true
371
+ v = v.to_f.to_s
372
+ end
373
+ if min_sigdig
374
+ v_parts = v.split(".")
375
+ decimal_str = v_parts[1]
376
+ if decimal_str == nil
377
+ v = v + "." + ('0' * min_sigdig)
378
+ elsif decimal_str.size < min_sigdig
379
+ v = v + ('0' * (min_sigdig - decimal_str.size))
380
+ end
381
+ end
382
+ v
370
383
  end
371
384
 
372
385
  def currency_sym(currency)
@@ -375,7 +388,7 @@ end
375
388
 
376
389
  # returns currency amount formatted like "$4,5123.00". 0.00 is formatted as "$0"
377
390
  # this is not ideal
378
- def format_money(amount, currency='usd', opts={})
391
+ def format_currency(amount, currency='usd', opts={})
379
392
  amount = amount.to_f
380
393
  if amount == 0
381
394
  return currency_sym(currency).to_s + "0"
@@ -383,8 +396,10 @@ def format_money(amount, currency='usd', opts={})
383
396
  # # return exponent notation like 3.4e-09
384
397
  # return currency_sym(currency).to_s + "#{amount}"
385
398
  else
386
- sigdig = opts[:sigdig] ? opts[:sigdig].to_i : 2
387
- rtn = currency_sym(currency).to_s + format_number(sprintf("%.#{sigdig}f", amount))
399
+ sigdig = opts[:sigdig] ? opts[:sigdig].to_i : 2 # max decimal digits
400
+ min_sigdig = opts[:min_sigdig] ? opts[:min_sigdig].to_i : 2 # min decimal digits
401
+ display_value = format_sig_dig(amount, sigdig, min_sigdig, opts[:pad_zeros])
402
+ rtn = currency_sym(currency).to_s + display_value
388
403
  if amount.to_i < 0
389
404
  rtn = "(#{rtn})"
390
405
  if opts[:minus_color]
@@ -394,3 +409,9 @@ def format_money(amount, currency='usd', opts={})
394
409
  rtn
395
410
  end
396
411
  end
412
+
413
+ alias :format_money :format_currency
414
+
415
+ # def format_money(amount, currency='usd', opts={})
416
+ # format_currency(amount, currency, opts)
417
+ # 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.22
4
+ version: 5.0.0
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-09-13 00:00:00.000000000 Z
14
+ date: 2020-09-29 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -185,8 +185,10 @@ files:
185
185
  - lib/morpheus/api/backup_jobs_interface.rb
186
186
  - lib/morpheus/api/backup_settings_interface.rb
187
187
  - lib/morpheus/api/backups_interface.rb
188
+ - lib/morpheus/api/billing_interface.rb
188
189
  - lib/morpheus/api/blueprints_interface.rb
189
190
  - lib/morpheus/api/budgets_interface.rb
191
+ - lib/morpheus/api/catalog_item_types_interface.rb
190
192
  - lib/morpheus/api/cloud_datastores_interface.rb
191
193
  - lib/morpheus/api/cloud_folders_interface.rb
192
194
  - lib/morpheus/api/cloud_policies_interface.rb
@@ -305,6 +307,7 @@ files:
305
307
  - lib/morpheus/cli/blueprints_command.rb
306
308
  - lib/morpheus/cli/boot_scripts_command.rb
307
309
  - lib/morpheus/cli/budgets_command.rb
310
+ - lib/morpheus/cli/catalog_command.rb
308
311
  - lib/morpheus/cli/change_password_command.rb
309
312
  - lib/morpheus/cli/cli_command.rb
310
313
  - lib/morpheus/cli/cli_registry.rb
@@ -333,6 +336,7 @@ files:
333
336
  - lib/morpheus/cli/commands/standard/source_command.rb
334
337
  - lib/morpheus/cli/commands/standard/ssl_verification_command.rb
335
338
  - lib/morpheus/cli/commands/standard/tee_command.rb
339
+ - lib/morpheus/cli/commands/standard/update_command.rb
336
340
  - lib/morpheus/cli/commands/standard/version_command.rb
337
341
  - lib/morpheus/cli/containers_command.rb
338
342
  - lib/morpheus/cli/credentials.rb
@@ -380,6 +384,7 @@ files:
380
384
  - lib/morpheus/cli/logs_command.rb
381
385
  - lib/morpheus/cli/mixins/accounts_helper.rb
382
386
  - lib/morpheus/cli/mixins/backups_helper.rb
387
+ - lib/morpheus/cli/mixins/catalog_helper.rb
383
388
  - lib/morpheus/cli/mixins/deployments_helper.rb
384
389
  - lib/morpheus/cli/mixins/infrastructure_helper.rb
385
390
  - lib/morpheus/cli/mixins/library_helper.rb
@@ -432,6 +437,7 @@ files:
432
437
  - lib/morpheus/cli/subnets_command.rb
433
438
  - lib/morpheus/cli/tasks.rb
434
439
  - lib/morpheus/cli/tenants_command.rb
440
+ - lib/morpheus/cli/usage_command.rb
435
441
  - lib/morpheus/cli/user_groups_command.rb
436
442
  - lib/morpheus/cli/user_settings_command.rb
437
443
  - lib/morpheus/cli/user_sources_command.rb