morpheus-cli 3.1.2.1 → 3.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.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/lib/morpheus/api/api_client.rb +6 -2
  3. data/lib/morpheus/api/license_interface.rb +7 -0
  4. data/lib/morpheus/api/monitoring_apps_interface.rb +15 -2
  5. data/lib/morpheus/api/{checks_interface.rb → monitoring_checks_interface.rb} +8 -21
  6. data/lib/morpheus/api/monitoring_groups_interface.rb +23 -2
  7. data/lib/morpheus/api/{incidents_interface.rb → monitoring_incidents_interface.rb} +5 -5
  8. data/lib/morpheus/api/monitoring_interface.rb +4 -4
  9. data/lib/morpheus/api/user_groups_interface.rb +65 -0
  10. data/lib/morpheus/cli.rb +1 -0
  11. data/lib/morpheus/cli/curl_command.rb +9 -7
  12. data/lib/morpheus/cli/dot_file.rb +11 -5
  13. data/lib/morpheus/cli/echo_command.rb +27 -3
  14. data/lib/morpheus/cli/license.rb +109 -20
  15. data/lib/morpheus/cli/login.rb +2 -0
  16. data/lib/morpheus/cli/logout.rb +2 -0
  17. data/lib/morpheus/cli/mixins/monitoring_helper.rb +97 -37
  18. data/lib/morpheus/cli/mixins/print_helper.rb +5 -2
  19. data/lib/morpheus/cli/monitoring_apps_command.rb +564 -9
  20. data/lib/morpheus/cli/monitoring_checks_command.rb +326 -93
  21. data/lib/morpheus/cli/monitoring_contacts_command.rb +2 -2
  22. data/lib/morpheus/cli/monitoring_groups_command.rb +540 -10
  23. data/lib/morpheus/cli/monitoring_incidents_command.rb +88 -56
  24. data/lib/morpheus/cli/remote.rb +6 -0
  25. data/lib/morpheus/cli/roles.rb +1 -1
  26. data/lib/morpheus/cli/set_prompt_command.rb +1 -0
  27. data/lib/morpheus/cli/shell.rb +17 -8
  28. data/lib/morpheus/cli/user_groups_command.rb +574 -0
  29. data/lib/morpheus/cli/users.rb +221 -115
  30. data/lib/morpheus/cli/version.rb +1 -1
  31. data/morpheus-cli.gemspec +1 -2
  32. metadata +11 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bd692a97b1bbed2d5e8ea4bbd23cdcd9a978fdcd
4
- data.tar.gz: 31761018c7d726c6f72dcf0a104eab21d441be08
3
+ metadata.gz: f32e58bc8431581ac6d29c7c8b2ff37b2f5084c2
4
+ data.tar.gz: 4f40c2a106aba9b340d3900c51bfa201b95d1ed4
5
5
  SHA512:
6
- metadata.gz: cd4f34da720c642384ddc9514d8c8175ba3a68188a8dc3b4b0b99968d3df524f7469f0be0a855a25977e51ddada333011dfb0385a4f810ff5d670e87361cdd76
7
- data.tar.gz: 9a754c3209288fac407ab5a86824415ddc31487232631a496436d946fa5061961579653837c93cd29240dc35cad33b0cd006c3f0267d8eb0965ea7cbf1a13e81
6
+ metadata.gz: 58d1640fdc65dba08ca947cdcb5969899ce652073291b44801549e266be28ba203367112cabcfbc89ae0ee91933c1e1dcd684b025dc4d6246d9857291a2848f1
7
+ data.tar.gz: c5a073c80d735dee9a2a68631d8663aa9824b4fcf534ad619a8a0385935362f1f960746ba1a8d492e5a0c5ecfe005415c5117eb184d9822e7e7c2e7b7f5eba26
@@ -141,6 +141,10 @@ class Morpheus::APIClient
141
141
  Morpheus::UsersInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
142
142
  end
143
143
 
144
+ def user_groups
145
+ Morpheus::UserGroupsInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
146
+ end
147
+
144
148
  def logs
145
149
  Morpheus::LogsInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
146
150
  end
@@ -182,12 +186,12 @@ class Morpheus::APIClient
182
186
  end
183
187
 
184
188
  # def checks
185
- # # Morpheus::ChecksInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
189
+ # # Morpheus::MonitoringChecksInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
186
190
  # monitoring.checks
187
191
  # end
188
192
 
189
193
  # def incidents
190
- # # Morpheus::IncidentsInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
194
+ # # Morpheus::MonitoringIncidentsInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
191
195
  # monitoring.incidents
192
196
  # end
193
197
 
@@ -21,4 +21,11 @@ class Morpheus::LicenseInterface < Morpheus::APIClient
21
21
  execute(method: :post, url: url, headers: headers, payload: payload.to_json)
22
22
  end
23
23
 
24
+ def decode(key)
25
+ url = "#{@base_url}/api/license/decode"
26
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
27
+ payload = {license: key}
28
+ execute(method: :post, url: url, headers: headers, payload: payload.to_json)
29
+ end
30
+
24
31
  end
@@ -37,11 +37,24 @@ class Morpheus::MonitoringAppsInterface < Morpheus::APIClient
37
37
  execute(opts)
38
38
  end
39
39
 
40
- def destroy(id)
40
+ def destroy(id, payload={})
41
41
  url = "#{@base_url}/api/monitoring/apps/#{id}"
42
42
  headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
43
- opts = {method: :delete, url: url, headers: headers}
43
+ opts = {method: :delete, url: url, headers: headers, payload: payload.to_json}
44
44
  execute(opts)
45
45
  end
46
46
 
47
+ def quarantine(id, payload={})
48
+ url = "#{@base_url}/api/monitoring/apps/#{id}/quarantine"
49
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
50
+ opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
51
+ execute(opts)
52
+ end
53
+
54
+ def statistics(id, params={})
55
+ url = "#{@base_url}/api/monitoring/apps/#{id}/statistics"
56
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
57
+ opts = {method: :get, url: url, headers: headers}
58
+ execute(opts)
59
+ end
47
60
  end
@@ -1,6 +1,6 @@
1
1
  require 'morpheus/api/api_client'
2
2
 
3
- class Morpheus::ChecksInterface < Morpheus::APIClient
3
+ class Morpheus::MonitoringChecksInterface < Morpheus::APIClient
4
4
  def initialize(access_token, refresh_token,expires_at = nil, base_url=nil)
5
5
  @access_token = access_token
6
6
  @refresh_token = refresh_token
@@ -23,14 +23,12 @@ class Morpheus::ChecksInterface < Morpheus::APIClient
23
23
  execute(opts)
24
24
  end
25
25
 
26
- # eh? maye use for rendering form
27
- # def create(options)
28
- # url = "#{@base_url}/api/monitoring/checks/create"
29
- # headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
30
- # payload = options
31
- # opts = {method: :post, url: url, headers: headers, payload: payload.to_json}
32
- # execute(opts)
33
- # end
26
+ def create(payload)
27
+ url = "#{@base_url}/api/monitoring/checks"
28
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
29
+ opts = {method: :post, url: url, headers: headers, payload: payload.to_json}
30
+ execute(opts)
31
+ end
34
32
 
35
33
  def update(id, options)
36
34
  url = "#{@base_url}/api/monitoring/checks/#{id}"
@@ -55,10 +53,6 @@ class Morpheus::ChecksInterface < Morpheus::APIClient
55
53
  execute(opts)
56
54
  end
57
55
 
58
- def mute(id, payload={})
59
- quarantine(id, payload)
60
- end
61
-
62
56
  def history(id, params={})
63
57
  url = "#{@base_url}/api/monitoring/checks/#{id}/history"
64
58
  headers = { params: params, authorization: "Bearer #{@access_token}" }
@@ -66,13 +60,6 @@ class Morpheus::ChecksInterface < Morpheus::APIClient
66
60
  execute(opts)
67
61
  end
68
62
 
69
- # def notifications(id)
70
- # url = "#{@base_url}/api/monitoring/checks/#{id}/notifications"
71
- # headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
72
- # opts = {method: :get, url: url, headers: headers}
73
- # execute(opts)
74
- # end
75
-
76
63
  def statistics(id)
77
64
  url = "#{@base_url}/api/monitoring/checks/#{id}/statistics"
78
65
  headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
@@ -93,7 +80,7 @@ class Morpheus::ChecksInterface < Morpheus::APIClient
93
80
  opts = {method: :get, url: url, headers: headers}
94
81
  execute(opts)
95
82
  end
96
-
83
+
97
84
  # def events(id, params={})
98
85
  # # JD: maybe switch to this instead /api/monitoring/checks/#{id}/events instead?
99
86
  # # url = "#{@base_url}/api/monitoring/checks/#{id}/events"
@@ -37,10 +37,31 @@ class Morpheus::MonitoringGroupsInterface < Morpheus::APIClient
37
37
  execute(opts)
38
38
  end
39
39
 
40
- def destroy(id)
40
+ def destroy(id, payload={})
41
41
  url = "#{@base_url}/api/monitoring/groups/#{id}"
42
42
  headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
43
- opts = {method: :delete, url: url, headers: headers}
43
+ opts = {method: :delete, url: url, headers: headers, payload: payload.to_json}
44
+ execute(opts)
45
+ end
46
+
47
+ def quarantine(id, payload={})
48
+ url = "#{@base_url}/api/monitoring/groups/#{id}/quarantine"
49
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
50
+ opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
51
+ execute(opts)
52
+ end
53
+
54
+ def history(id, params={})
55
+ url = "#{@base_url}/api/monitoring/groups/#{id}/history"
56
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
57
+ opts = {method: :get, url: url, headers: headers}
58
+ execute(opts)
59
+ end
60
+
61
+ def statistics(id)
62
+ url = "#{@base_url}/api/monitoring/groups/#{id}/statistics"
63
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
64
+ opts = {method: :get, url: url, headers: headers}
44
65
  execute(opts)
45
66
  end
46
67
 
@@ -1,6 +1,6 @@
1
1
  require 'morpheus/api/api_client'
2
2
 
3
- class Morpheus::IncidentsInterface < Morpheus::APIClient
3
+ class Morpheus::MonitoringIncidentsInterface < Morpheus::APIClient
4
4
  def initialize(access_token, refresh_token,expires_at = nil, base_url=nil)
5
5
  @access_token = access_token
6
6
  @refresh_token = refresh_token
@@ -46,10 +46,10 @@ class Morpheus::IncidentsInterface < Morpheus::APIClient
46
46
  execute(opts)
47
47
  end
48
48
 
49
- def destroy(id)
49
+ def destroy(id, payload={})
50
50
  url = "#{@base_url}/api/monitoring/incidents/#{id}"
51
51
  headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
52
- opts = {method: :delete, url: url, headers: headers}
52
+ opts = {method: :delete, url: url, headers: headers, payload: payload.to_json}
53
53
  execute(opts)
54
54
  end
55
55
 
@@ -90,11 +90,11 @@ class Morpheus::IncidentsInterface < Morpheus::APIClient
90
90
  execute(opts)
91
91
  end
92
92
 
93
- def events(id)
93
+ def events(id, params={})
94
94
  # JD: maybe switch to this instead /api/monitoring/incidents/#{id}/events instead?
95
95
  # url = "#{@base_url}/api/monitoring/incidents/#{id}/events"
96
96
  url = "#{@base_url}/api/monitoring/incident-events/#{id}"
97
- headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
97
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
98
98
  opts = {method: :get, url: url, headers: headers}
99
99
  execute(opts)
100
100
  end
@@ -1,6 +1,6 @@
1
1
  require 'morpheus/api/api_client'
2
- require 'morpheus/api/checks_interface'
3
- require 'morpheus/api/incidents_interface'
2
+ require 'morpheus/api/monitoring_checks_interface'
3
+ require 'morpheus/api/monitoring_incidents_interface'
4
4
  require 'morpheus/api/monitoring_contacts_interface'
5
5
  require 'morpheus/api/monitoring_groups_interface'
6
6
  require 'morpheus/api/monitoring_apps_interface'
@@ -14,11 +14,11 @@ class Morpheus::MonitoringInterface < Morpheus::APIClient
14
14
  end
15
15
 
16
16
  def checks
17
- Morpheus::ChecksInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
17
+ Morpheus::MonitoringChecksInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
18
18
  end
19
19
 
20
20
  def incidents
21
- Morpheus::IncidentsInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
21
+ Morpheus::MonitoringIncidentsInterface.new(@access_token, @refresh_token, @expires_at, @base_url)
22
22
  end
23
23
 
24
24
  def contacts
@@ -0,0 +1,65 @@
1
+ require 'morpheus/api/api_client'
2
+
3
+ class Morpheus::UserGroupsInterface < Morpheus::APIClient
4
+ def initialize(access_token, refresh_token, expires_at = nil, base_url=nil)
5
+ @access_token = access_token
6
+ @refresh_token = refresh_token
7
+ @base_url = base_url
8
+ @expires_at = expires_at
9
+ end
10
+
11
+ def get(account_id, id)
12
+ raise "#{self.class}.get() passed a blank id!" if id.to_s == ''
13
+ url = build_url(account_id, id)
14
+ headers = { params: {}, authorization: "Bearer #{@access_token}" }
15
+ opts = {method: :get, url: url, timeout: 10, headers: headers}
16
+ execute(opts)
17
+ end
18
+
19
+ def list(account_id, options={})
20
+ url = build_url(account_id)
21
+ headers = { params: {}, authorization: "Bearer #{@access_token}" }
22
+ headers[:params].merge!(options)
23
+ opts = {method: :get, url: url, timeout: 10, headers: headers}
24
+ execute(opts)
25
+ end
26
+
27
+ def create(account_id, options)
28
+ url = build_url(account_id)
29
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
30
+ payload = options
31
+ opts = {method: :post, url: url, timeout: 10, headers: headers, payload: payload.to_json}
32
+ execute(opts)
33
+ end
34
+
35
+ def update(account_id, id, options)
36
+ url = build_url(account_id, id)
37
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
38
+ payload = options
39
+ opts = {method: :put, url: url, timeout: 10, headers: headers, payload: payload.to_json}
40
+ execute(opts)
41
+ end
42
+
43
+ def destroy(account_id, id)
44
+ url = build_url(account_id, id)
45
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
46
+ opts = {method: :delete, url: url, timeout: 10, headers: headers}
47
+ execute(opts)
48
+ end
49
+
50
+ private
51
+
52
+ def build_url(account_id=nil, user_id=nil)
53
+ url = "#{@base_url}/api"
54
+ if account_id
55
+ url += "/accounts/#{account_id}/user-groups"
56
+ else
57
+ url += "/user-groups"
58
+ end
59
+ if user_id
60
+ url += "/#{user_id}"
61
+ end
62
+ url
63
+ end
64
+
65
+ end
data/lib/morpheus/cli.rb CHANGED
@@ -79,6 +79,7 @@ module Morpheus
79
79
  load 'morpheus/cli/security_group_rules.rb'
80
80
  load 'morpheus/cli/accounts.rb'
81
81
  load 'morpheus/cli/users.rb'
82
+ load 'morpheus/cli/user_groups_command.rb'
82
83
  load 'morpheus/cli/roles.rb'
83
84
  load 'morpheus/cli/key_pairs.rb'
84
85
  load 'morpheus/cli/virtual_images.rb'
@@ -49,12 +49,12 @@ EOT
49
49
  curl_args.unshift "--inescure"
50
50
  end
51
51
 
52
- creds = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).load_saved_credentials()
53
- if !creds
54
- print yellow,"You are not currently logged in to #{display_appliance(@appliance_name, @appliance_url)}",reset,"\n"
55
- print yellow,"Use the 'login' command.",reset,"\n"
56
- return 0
57
- end
52
+ # @access_token = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).load_saved_credentials()
53
+ # if !@access_token
54
+ # print yellow,"You are not currently logged in to #{display_appliance(@appliance_name, @appliance_url)}",reset,"\n"
55
+ # print yellow,"Use the 'login' command.",reset,"\n"
56
+ # return 0
57
+ # end
58
58
 
59
59
  if !@appliance_url
60
60
  raise "Unable to determine remote appliance url"
@@ -67,7 +67,9 @@ EOT
67
67
  api_path = args[0].sub(/^\//, "")
68
68
  url = "#{base_url}/#{api_path}"
69
69
  curl_cmd = "curl \"#{url}\""
70
- curl_cmd << " -H \"Authorization: Bearer #{@access_token}\""
70
+ if @access_token
71
+ curl_cmd << " -H \"Authorization: Bearer #{@access_token}\""
72
+ end
71
73
  if !curl_args.empty?
72
74
  curl_cmd << " " + curl_args.join(' ')
73
75
  end
@@ -55,16 +55,22 @@ class Morpheus::Cli::DotFile
55
55
 
56
56
  # print "#{dark} #=> executing source file line #{line_num}: #{line}#{reset}\n" if Morpheus::Logging.debug?
57
57
 
58
- # todo: allow semicolons inside arguments too..
59
- command_list = line.strip.split(';').compact
58
+ # allow semicolons inside arguments too..
59
+ #command_list = line.strip.split(';').compact
60
+ command_list = line.split(/(;)(?=(?:[^"']|["|'][^"']*")*$)/).reject {|it| it.to_s.strip.empty? || it.to_s.strip == ";" }
60
61
  command_list.each do |input|
61
62
  input = input.strip
62
63
  if input.empty?
63
64
  next
64
65
  end
65
- argv = Shellwords.shellsplit(input)
66
-
67
- if Morpheus::Cli::CliRegistry.has_command?(argv[0]) || Morpheus::Cli::CliRegistry.has_alias?(argv[0])
66
+ argv = nil
67
+ begin
68
+ argv = Shellwords.shellsplit(input)
69
+ rescue => err
70
+ cmd_result = false
71
+ puts "#{red} Unparsable source file: #{@filename} line: #{line_num} '#{input}' #{reset} - #{err}"
72
+ end
73
+ if argv[0] && Morpheus::Cli::CliRegistry.has_command?(argv[0]) || Morpheus::Cli::CliRegistry.has_alias?(argv[0])
68
74
  #log_history_command(input)
69
75
  cmd_result = nil
70
76
  begin
@@ -1,13 +1,33 @@
1
- require 'optparse'
2
1
  require 'morpheus/cli/cli_command'
2
+ require 'term/ansicolor'
3
3
  require 'json'
4
4
 
5
- # This is for use in dotfile scripts
6
- class Morpheus::Cli::EchoCommand
5
+ # This is for use in dotfile scripts for printing
6
+ # It is also responsible for maintaining a map of variables
7
+ # that are also used in custom shell prompts.
8
+ class Morpheus::Cli::Echo
7
9
  include Morpheus::Cli::CliCommand
8
10
  set_command_name :echo
9
11
  set_command_hidden
10
12
 
13
+ unless defined?(DEFAULT_VARIABLE_MAP)
14
+ DEFAULT_VARIABLE_MAP = {'%cyan' => Term::ANSIColor.cyan, '%magenta' => Term::ANSIColor.magenta, '%red' => Term::ANSIColor.red, '%green' => Term::ANSIColor.green, '%yellow' => Term::ANSIColor.yellow, '%dark' => Term::ANSIColor.dark, '%reset' => Term::ANSIColor.reset}
15
+ end
16
+
17
+ def self.variable_map
18
+ @output_variable_map ||= recalculate_variable_map()
19
+ end
20
+
21
+ def self.recalculate_variable_map()
22
+ var_map = {}
23
+ var_map.merge!(DEFAULT_VARIABLE_MAP)
24
+ appliance = ::Morpheus::Cli::Remote.load_active_remote()
25
+ if appliance
26
+ var_map.merge!({'%remote' => appliance[:name], '%remote_url' => appliance[:host], '%username' => appliance[:username]})
27
+ end
28
+ @output_variable_map = var_map
29
+ end
30
+
11
31
  def handle(args)
12
32
  append_newline = true
13
33
  options = {}
@@ -21,6 +41,10 @@ class Morpheus::Cli::EchoCommand
21
41
  optparse.parse!(args)
22
42
  out = ""
23
43
  out << args.join(' ')
44
+
45
+ self.class.variable_map.each do |k, v|
46
+ out.gsub!(k.to_s, v.to_s)
47
+ end
24
48
  if append_newline
25
49
  out << "\n"
26
50
  end
@@ -7,7 +7,7 @@ require 'morpheus/cli/cli_command'
7
7
  class Morpheus::Cli::License
8
8
  include Morpheus::Cli::CliCommand
9
9
 
10
- register_subcommands :get, :apply
10
+ register_subcommands :get, :apply, :decode
11
11
  alias_subcommand :details, :get
12
12
 
13
13
  def initialize()
@@ -26,7 +26,7 @@ class Morpheus::Cli::License
26
26
 
27
27
  def get(args)
28
28
  options = {}
29
- optparse = OptionParser.new do|opts|
29
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
30
30
  opts.banner = subcommand_usage()
31
31
  build_common_options(opts, options, [:json, :dry_run, :remote])
32
32
  end
@@ -37,26 +37,38 @@ class Morpheus::Cli::License
37
37
  print_dry_run @license_interface.dry.get()
38
38
  return
39
39
  end
40
- license = @license_interface.get()
40
+ json_result = @license_interface.get()
41
+ license = json_result['license']
42
+ used_memory = json_result['licenseUsedMemory']
41
43
  if options[:json]
42
- puts JSON.pretty_generate(license)
44
+ puts JSON.pretty_generate(json_result)
43
45
  else
44
- if license['license'].nil?
45
- puts "No License Currently Applied to the appliance."
46
- exit 1
46
+ if license.nil?
47
+ puts_error "No license currently applied to the appliance."
48
+ return 1
47
49
  else
48
50
  print_h1 "License"
49
- max_memory = Filesize.from("#{license['license']['maxMemory']} B").pretty
50
- max_storage = Filesize.from("#{license['license']['maxStorage']} B").pretty
51
- used_memory = Filesize.from("#{license['usedMemory']} B").pretty
52
- puts "Account: #{license['license']['accountName']}"
53
- puts "Start Date: #{license['license']['startDate']}"
54
- puts "End Date: #{license['license']['endDate']}"
55
- puts "Memory: #{used_memory} / #{max_memory}"
56
- puts "Max Storage: #{max_storage}"
51
+ max_memory = "Unlimited"
52
+ max_storage = "Unlimited"
53
+ max_memory = Filesize.from("#{license['maxMemory']} B").pretty if license['maxMemory'].to_i != 0
54
+ max_storage = Filesize.from("#{license['maxStorage']} B").pretty if license['maxStorage'].to_i != 0
55
+ used_memory = Filesize.from("#{used_memory} B").pretty if used_memory.to_i != 0
56
+ print cyan
57
+ description_cols = {
58
+ "Account" => 'accountName',
59
+ "Product Tier" => lambda {|it| format_product_tier(it) },
60
+ "Start Date" => lambda {|it| format_local_dt(it['startDate']) },
61
+ "End Date" => lambda {|it| format_local_dt(it['endDate']) },
62
+ "Memory" => lambda {|it| "#{used_memory} / #{max_memory}" },
63
+ "Max Storage" => lambda {|it| "#{max_storage}" },
64
+ "Max Instances" => lambda {|it| it["maxInstances"].to_i == 0 ? 'Unlimited' : it["maxInstances"] },
65
+ "Hard Limit" => lambda {|it| it[""] == false ? 'Yes' : 'No' },
66
+ }
67
+ print_description_list(description_cols, license)
68
+ print reset,"\n"
57
69
  end
58
- print reset,"\n"
59
70
  end
71
+ return 0
60
72
  rescue RestClient::Exception => e
61
73
  print_rest_exception(e, options)
62
74
  return false
@@ -66,7 +78,7 @@ class Morpheus::Cli::License
66
78
  def apply(args)
67
79
  options = {}
68
80
  account_name = nil
69
- optparse = OptionParser.new do|opts|
81
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
70
82
  opts.banner = subcommand_usage("[key]")
71
83
  build_common_options(opts, options, [:json, :dry_run, :remote])
72
84
  end
@@ -81,18 +93,95 @@ class Morpheus::Cli::License
81
93
  end
82
94
  if options[:dry_run]
83
95
  print_dry_run @license_interface.dry.apply(key)
96
+ return 0
97
+ end
98
+ json_result = @license_interface.apply(key)
99
+ license = json_result['license']
100
+ if options[:json]
101
+ puts JSON.pretty_generate(json_result)
102
+ else
103
+ print_green_success "License applied successfully!"
104
+ # get([]) # show it
105
+ end
106
+ return 0
107
+ rescue RestClient::Exception => e
108
+ print_rest_exception(e, options)
109
+ return false
110
+ end
111
+ end
112
+
113
+ def decode(args)
114
+ options = {}
115
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
116
+ opts.banner = subcommand_usage("[key]")
117
+ build_common_options(opts, options, [:json, :dry_run, :remote])
118
+ opts.footer = "Decode a license key."
119
+ end
120
+ optparse.parse!(args)
121
+ connect(options)
122
+ key = nil
123
+ if args[0]
124
+ key = args[0]
125
+ else
126
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'licenseKey', 'fieldLabel' => 'License Key', 'type' => 'text', 'required' => true}], options[:options])
127
+ key = v_prompt['licenseKey'] || ''
128
+ end
129
+ begin
130
+ if options[:dry_run]
131
+ print_dry_run @license_interface.dry.decode(key)
84
132
  return
85
133
  end
86
- license_results = @license_interface.apply(key)
134
+ json_result = @license_interface.decode(key)
135
+ license = json_result['license']
87
136
  if options[:json]
88
- puts JSON.pretty_generate(license_results)
137
+ puts JSON.pretty_generate(json_result)
89
138
  else
90
- puts "License applied successfully!"
139
+ if license.nil?
140
+ puts_error "Unable to decode license."
141
+ puts_error json_results['msg'] if json_results['msg']
142
+ return 1
143
+ else
144
+ print_h1 "License"
145
+ max_memory = "Unlimited"
146
+ max_storage = "Unlimited"
147
+ max_memory = Filesize.from("#{license['maxMemory']} B").pretty if license['maxMemory'].to_i != 0
148
+ max_storage = Filesize.from("#{license['maxStorage']} B").pretty if license['maxStorage'].to_i != 0
149
+ print cyan
150
+ description_cols = {
151
+ "Account" => 'accountName',
152
+ "Product Tier" => lambda {|it| format_product_tier(it) },
153
+ "Start Date" => lambda {|it| format_local_dt(it['startDate']) },
154
+ "End Date" => lambda {|it| format_local_dt(it['endDate']) },
155
+ "Max Memory" => lambda {|it| max_memory },
156
+ "Max Storage" => lambda {|it| max_storage },
157
+ "Max Instances" => lambda {|it| it["maxInstances"].to_i == 0 ? 'Unlimited' : it["maxInstances"] },
158
+ "Hard Limit" => lambda {|it| it[""] == false ? 'Yes' : 'No' },
159
+ }
160
+ print_description_list(description_cols, license)
161
+ print reset,"\n"
162
+ end
91
163
  end
164
+ return 0
92
165
  rescue RestClient::Exception => e
93
166
  print_rest_exception(e, options)
94
167
  return false
95
168
  end
96
169
  end
97
170
 
171
+ def format_product_tier(license)
172
+ product_tier = license['productTier'] || 'capacity'
173
+ if product_tier == 'capacity'
174
+ 'Capacity'
175
+ elsif product_tier == 'essentials'
176
+ 'Essentials'
177
+ elsif product_tier == 'pro'
178
+ 'Pro'
179
+ elsif product_tier == 'enterprise'
180
+ 'Enterprise'
181
+ elsif product_tier == 'msp'
182
+ 'Service Provider'
183
+ else
184
+ product_tier.to_s.capitalize
185
+ end
186
+ end
98
187
  end