morpheus-cli 5.5.2.2 → 5.5.3.1

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 (132) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/Dockerfile +1 -1
  4. data/README.md +57 -4
  5. data/Rakefile +9 -0
  6. data/bin/morpheus +4 -4
  7. data/lib/morpheus/api/api_client.rb +20 -2
  8. data/lib/morpheus/api/appliance_settings_interface.rb +15 -0
  9. data/lib/morpheus/api/archive_buckets_interface.rb +1 -1
  10. data/lib/morpheus/api/archive_files_interface.rb +3 -3
  11. data/lib/morpheus/api/clients_interface.rb +2 -2
  12. data/lib/morpheus/api/clusters_interface.rb +8 -1
  13. data/lib/morpheus/api/containers_interface.rb +29 -16
  14. data/lib/morpheus/api/custom_instance_types_interface.rb +0 -2
  15. data/lib/morpheus/api/cypher_interface.rb +1 -2
  16. data/lib/morpheus/api/doc_interface.rb +8 -6
  17. data/lib/morpheus/api/file_copy_request_interface.rb +1 -1
  18. data/lib/morpheus/api/guidance_settings_interface.rb +17 -0
  19. data/lib/morpheus/api/health_interface.rb +1 -1
  20. data/lib/morpheus/api/image_builder_interface.rb +3 -3
  21. data/lib/morpheus/api/instances_interface.rb +25 -0
  22. data/lib/morpheus/api/logs_interface.rb +2 -4
  23. data/lib/morpheus/api/monitoring_interface.rb +6 -6
  24. data/lib/morpheus/api/monitoring_settings_interface.rb +25 -0
  25. data/lib/morpheus/api/network_server_groups_interface.rb +7 -0
  26. data/lib/morpheus/api/packages_interface.rb +1 -1
  27. data/lib/morpheus/api/reports_interface.rb +1 -1
  28. data/lib/morpheus/api/servers_interface.rb +9 -1
  29. data/lib/morpheus/api/storage_providers_interface.rb +2 -2
  30. data/lib/morpheus/api/virtual_images_interface.rb +1 -1
  31. data/lib/morpheus/api.rb +2 -0
  32. data/lib/morpheus/benchmarking.rb +1 -1
  33. data/lib/morpheus/cli/cli_command.rb +79 -37
  34. data/lib/morpheus/cli/cli_registry.rb +19 -10
  35. data/lib/morpheus/cli/commands/access_token_command.rb +1 -1
  36. data/lib/morpheus/cli/commands/appliance_settings_command.rb +57 -2
  37. data/lib/morpheus/cli/commands/apps.rb +1 -1
  38. data/lib/morpheus/cli/commands/archives_command.rb +25 -33
  39. data/lib/morpheus/cli/commands/backup_settings_command.rb +1 -1
  40. data/lib/morpheus/cli/commands/blueprints_command.rb +10 -21
  41. data/lib/morpheus/cli/commands/boot_scripts_command.rb +2 -2
  42. data/lib/morpheus/cli/commands/cat_command.rb +1 -1
  43. data/lib/morpheus/cli/commands/catalog_item_types_command.rb +18 -13
  44. data/lib/morpheus/cli/commands/clouds.rb +3 -3
  45. data/lib/morpheus/cli/commands/clusters.rb +154 -3
  46. data/lib/morpheus/cli/commands/containers_command.rb +398 -253
  47. data/lib/morpheus/cli/commands/cypher_command.rb +3 -0
  48. data/lib/morpheus/cli/commands/deployments.rb +1 -1
  49. data/lib/morpheus/cli/commands/deploys.rb +9 -9
  50. data/lib/morpheus/cli/commands/doc.rb +15 -16
  51. data/lib/morpheus/cli/commands/execution_request_command.rb +2 -2
  52. data/lib/morpheus/cli/commands/file_copy_request_command.rb +5 -5
  53. data/lib/morpheus/cli/commands/groups.rb +2 -2
  54. data/lib/morpheus/cli/commands/guidance_command.rb +2 -2
  55. data/lib/morpheus/cli/commands/guidance_settings.rb +148 -0
  56. data/lib/morpheus/cli/commands/health_command.rb +4 -4
  57. data/lib/morpheus/cli/commands/hosts.rb +43 -5
  58. data/lib/morpheus/cli/commands/image_builder_command.rb +1 -1
  59. data/lib/morpheus/cli/commands/instances.rb +419 -148
  60. data/lib/morpheus/cli/commands/integrations_command.rb +22 -20
  61. data/lib/morpheus/cli/commands/key_pairs.rb +2 -2
  62. data/lib/morpheus/cli/commands/library_container_scripts_command.rb +2 -2
  63. data/lib/morpheus/cli/commands/library_container_templates_command.rb +2 -2
  64. data/lib/morpheus/cli/commands/library_instance_types_command.rb +3 -3
  65. data/lib/morpheus/cli/commands/library_spec_templates_command.rb +2 -2
  66. data/lib/morpheus/cli/commands/log_settings_command.rb +1 -1
  67. data/lib/morpheus/cli/commands/login.rb +1 -1
  68. data/lib/morpheus/cli/commands/man_command.rb +32 -18
  69. data/lib/morpheus/cli/commands/monitoring_settings.rb +228 -0
  70. data/lib/morpheus/cli/commands/network_server_groups_command.rb +222 -0
  71. data/lib/morpheus/cli/commands/packages_command.rb +11 -11
  72. data/lib/morpheus/cli/commands/plugins.rb +1 -1
  73. data/lib/morpheus/cli/commands/policies_command.rb +4 -4
  74. data/lib/morpheus/cli/commands/preseed_scripts_command.rb +2 -2
  75. data/lib/morpheus/cli/commands/provisioning_settings_command.rb +1 -1
  76. data/lib/morpheus/cli/commands/remote.rb +1 -1
  77. data/lib/morpheus/cli/commands/reports_command.rb +13 -3
  78. data/lib/morpheus/cli/commands/security_groups.rb +1 -1
  79. data/lib/morpheus/cli/commands/shell.rb +40 -62
  80. data/lib/morpheus/cli/commands/snapshots.rb +3 -5
  81. data/lib/morpheus/cli/commands/source_command.rb +8 -16
  82. data/lib/morpheus/cli/commands/storage_providers_command.rb +7 -7
  83. data/lib/morpheus/cli/commands/tasks.rb +2 -2
  84. data/lib/morpheus/cli/commands/vdi_pools_command.rb +6 -6
  85. data/lib/morpheus/cli/commands/view.rb +5 -1
  86. data/lib/morpheus/cli/commands/whitelabel_settings_command.rb +5 -5
  87. data/lib/morpheus/cli/commands/whoami.rb +2 -2
  88. data/lib/morpheus/cli/credentials.rb +30 -8
  89. data/lib/morpheus/cli/dot_file.rb +8 -15
  90. data/lib/morpheus/cli/error_handler.rb +16 -0
  91. data/lib/morpheus/cli/errors.rb +8 -1
  92. data/lib/morpheus/cli/mixins/print_helper.rb +17 -13
  93. data/lib/morpheus/cli/mixins/provisioning_helper.rb +14 -12
  94. data/lib/morpheus/cli/mixins/rest_command.rb +23 -19
  95. data/lib/morpheus/cli/mixins/secondary_rest_command.rb +47 -24
  96. data/lib/morpheus/cli/option_parser.rb +5 -1
  97. data/lib/morpheus/cli/option_types.rb +59 -12
  98. data/lib/morpheus/cli/version.rb +1 -1
  99. data/lib/morpheus/cli.rb +26 -16
  100. data/lib/morpheus/ext/rest_client.rb +3 -2
  101. data/lib/morpheus/ext/string.rb +6 -4
  102. data/lib/morpheus/formatters.rb +1 -1
  103. data/lib/morpheus/logging.rb +4 -4
  104. data/lib/morpheus/morpkg.rb +4 -4
  105. data/lib/morpheus/rest_client.rb +2 -2
  106. data/lib/morpheus/routes.rb +41 -9
  107. data/lib/morpheus/terminal.rb +65 -16
  108. data/lib/morpheus.rb +1 -1
  109. data/morpheus-cli.gemspec +1 -0
  110. data/test/api/containers_interface_test.rb +68 -0
  111. data/test/api/doc_interface_test.rb +35 -0
  112. data/test/api/instances_interface_test.rb +22 -0
  113. data/test/api/whoami_interface_test.rb +14 -0
  114. data/test/cli/access_token_test.rb +36 -0
  115. data/test/cli/auth_test.rb +82 -0
  116. data/test/cli/cli_test.rb +48 -0
  117. data/test/cli/containers_test.rb +92 -0
  118. data/test/cli/doc_test.rb +35 -0
  119. data/test/cli/help_test.rb +25 -0
  120. data/test/cli/instances_test.rb +36 -0
  121. data/test/cli/man_test.rb +14 -0
  122. data/test/cli/remote_test.rb +89 -0
  123. data/test/cli/roles_test.rb +34 -0
  124. data/test/cli/shell_test.rb +81 -0
  125. data/test/cli/version_test.rb +23 -0
  126. data/test/cli/view_test.rb +55 -0
  127. data/test/cli/whoami_test.rb +17 -0
  128. data/test/morpheus_test.rb +16 -0
  129. data/test/test_case.rb +338 -0
  130. data/test/test_config.rb +137 -0
  131. data/test/test_data_helper.rb +97 -0
  132. metadata +67 -3
@@ -14,12 +14,25 @@ module Morpheus
14
14
  default_value = options[:default]
15
15
  value_found = false
16
16
  while value_found == false do
17
+ # if default_value.nil?
18
+ # print "#{message} (yes/no): "
19
+ # else
20
+ # print "#{message} (yes/no) [#{!!default_value ? 'yes' : 'no'}]: "
21
+ # end
22
+ # input = $stdin.gets.chomp!
23
+
24
+ # should use Readline.readline to probably
25
+ Readline.completion_append_character = ""
26
+ Readline.basic_word_break_characters = ''
27
+ Readline.completion_proc = nil
17
28
  if default_value.nil?
18
- print "#{message} (yes/no): "
29
+ confirm_prompt = "#{message} (yes/no): "
19
30
  else
20
- print "#{message} (yes/no) [#{!!default_value ? 'yes' : 'no'}]: "
31
+ confirm_prompt = "#{message} (yes/no) [#{!!default_value ? 'yes' : 'no'}]: "
21
32
  end
22
- input = $stdin.gets.chomp!
33
+ input = Readline.readline(confirm_prompt, false).to_s
34
+ input = input.chomp.strip
35
+
23
36
  if input.empty? && !default_value.nil?
24
37
  return !!default_value
25
38
  end
@@ -86,6 +99,25 @@ module Morpheus
86
99
  context_map = results
87
100
  value = nil
88
101
  value_found = false
102
+
103
+ # allow for mapping of domain to relevant type: domain.zone => router.zone
104
+ option_type['fieldContext'] = (options[:context_map] || {})[option_type['fieldContext']] || option_type['fieldContext']
105
+ field_key = [option_type['fieldContext'], option_type['fieldName']].select {|it| it && it != '' }.join('.')
106
+ help_field_key = option_type[:help_field_prefix] ? "#{option_type[:help_field_prefix]}.#{field_key}" : field_key
107
+ namespaces = field_key.split(".")
108
+ field_name = namespaces.pop
109
+
110
+
111
+ # support --no-options --skip-option x,y,z --only-option x,y,z
112
+ if options[:no_options]
113
+ next
114
+ elsif options[:skip_options] && options[:skip_options].find {|it| it.to_s.downcase == option_type['fieldName'].to_s.downcase || it.to_s.downcase == option_type['fieldLabel'].to_s.downcase }
115
+ next
116
+ elsif options[:only_options] && !options[:only_options].find {|it| it.to_s.downcase == option_type['fieldName'].to_s.downcase || it.to_s.downcase == option_type['fieldLabel'].to_s.downcase }
117
+ next
118
+ end
119
+
120
+
89
121
  field_group = (option_type['fieldGroup'] || 'default').to_s.sub(/options\Z/i, "").strip # avoid "ADVANCED OPTION OPTIONS"
90
122
 
91
123
  if cur_field_group != field_group
@@ -105,12 +137,6 @@ module Morpheus
105
137
  # end
106
138
  # end
107
139
 
108
- # allow for mapping of domain to relevant type: domain.zone => router.zone
109
- option_type['fieldContext'] = (options[:context_map] || {})[option_type['fieldContext']] || option_type['fieldContext']
110
- field_key = [option_type['fieldContext'], option_type['fieldName']].select {|it| it && it != '' }.join('.')
111
- help_field_key = option_type[:help_field_prefix] ? "#{option_type[:help_field_prefix]}.#{field_key}" : field_key
112
- namespaces = field_key.split(".")
113
- field_name = namespaces.pop
114
140
 
115
141
  # respect optionType.dependsOnCode
116
142
  # i guess this switched to visibleOnCode, respect one or the other
@@ -612,6 +638,7 @@ module Morpheus
612
638
  end
613
639
 
614
640
  while !value_found do
641
+ #Readline.input = $stdin
615
642
  Readline.completion_append_character = ""
616
643
  Readline.basic_word_break_characters = ''
617
644
  Readline.completion_proc = proc {|s|
@@ -703,6 +730,7 @@ module Morpheus
703
730
  elsif no_prompt
704
731
  input = default_value
705
732
  else
733
+ #Readline.input = $stdin
706
734
  Readline.completion_append_character = ""
707
735
  Readline.basic_word_break_characters = ''
708
736
  Readline.completion_proc = proc {|s|
@@ -970,8 +998,26 @@ module Morpheus
970
998
  def self.password_prompt(option_type)
971
999
  value_found = false
972
1000
  while !value_found do
973
- print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? (' (' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+'************'+']' : ''}: "
974
- input = $stdin.noecho(&:gets).chomp!
1001
+ # readline is still echoing secret with 'NUL:'' so just use $stdin on windows for now
1002
+ if Morpheus::Cli.windows?
1003
+ print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? (' (' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+'************'+']' : ''}: "
1004
+ input = $stdin.noecho(&:gets).chomp!
1005
+ else
1006
+ Readline.completion_append_character = ""
1007
+ Readline.basic_word_break_characters = ''
1008
+ Readline.completion_proc = nil
1009
+ # needs to work like $stdin.noecho
1010
+ Readline.pre_input_hook = lambda {
1011
+ Readline.output = File.open('/dev/null', 'w')
1012
+ #Readline.output = File.open(Morpheus::Cli.windows? ? 'NUL:' : '/dev/null', 'w')
1013
+ #$stdout = File.open(Morpheus::Cli.windows? ? 'NUL:' : '/dev/null', 'w')
1014
+ }
1015
+ password_prompt = "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? (' (' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+'************'+']' : ''}: "
1016
+ input = Readline.readline(password_prompt, false).to_s.chomp
1017
+ Readline.pre_input_hook = nil
1018
+ Readline.output = Morpheus::Terminal.instance.stdout #my_terminal.stdout
1019
+ end
1020
+
975
1021
  value = input
976
1022
  print "\n"
977
1023
  if input == '?'
@@ -991,6 +1037,7 @@ module Morpheus
991
1037
  value = nil
992
1038
  while !value_found do
993
1039
  #print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? (' (' + option_type['fieldAddOn'] + ') ') : '' }#{optional_label(option_type)}#{option_type['defaultValue'] ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
1040
+ #Readline.input = $stdin
994
1041
  Readline.completion_append_character = ""
995
1042
  Readline.basic_word_break_characters = ''
996
1043
  Readline.completion_proc = proc {|s| Readline::FILENAME_COMPLETION_PROC.call(s) }
@@ -1005,7 +1052,7 @@ module Morpheus
1005
1052
  value_found = true
1006
1053
  elsif value
1007
1054
  filename = File.expand_path(value)
1008
- if !File.exists?(filename)
1055
+ if !File.exist?(filename)
1009
1056
  # print_red_alert "File not found: #{filename}"
1010
1057
  # exit 1
1011
1058
  print Term::ANSIColor.red," File not found: #{filename}",Term::ANSIColor.reset, "\n"
@@ -1,6 +1,6 @@
1
1
 
2
2
  module Morpheus
3
3
  module Cli
4
- VERSION = "5.5.2.2"
4
+ VERSION = "5.5.3.1"
5
5
  end
6
6
  end
data/lib/morpheus/cli.rb CHANGED
@@ -36,38 +36,48 @@ module Morpheus
36
36
  begin
37
37
  require 'rbconfig'
38
38
  @@is_windows = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
39
- rescue => ex
39
+ rescue
40
40
  # $stderr.puts "unable to determine if this is a Windows machine."
41
41
  end
42
42
  return @@is_windows
43
43
  end
44
44
 
45
- # load all the well known commands and utilties they need
45
+ # load! does the initial loading of all the CLI utilities and commands
46
46
  def self.load!()
47
- # load interfaces
48
- require 'morpheus/api/api_client.rb'
49
- require 'morpheus/api/rest_interface.rb'
50
- require 'morpheus/api/read_interface.rb'
51
- Dir[File.dirname(__FILE__) + "/api/**/*.rb"].each {|file| load file }
52
-
53
- # load mixins
54
- Dir[File.dirname(__FILE__) + "/cli/mixins/**/*.rb"].each {|file| load file }
47
+
48
+ # api interfaces
49
+ require 'morpheus/api'
50
+ Dir[File.dirname(__FILE__) + "/api/**/*.rb"].each { |file| require file }
55
51
 
56
- # load utilites
52
+ # utilites
53
+ # Dir[File.dirname(__FILE__) + "/cli/*.rb"].each { |file| require file }
57
54
  require 'morpheus/cli/cli_registry.rb'
58
55
  require 'morpheus/cli/expression_parser.rb'
59
56
  require 'morpheus/cli/dot_file.rb'
60
57
  require 'morpheus/cli/errors'
58
+ require 'morpheus/cli/cli_command.rb'
59
+ require 'morpheus/cli/option_types.rb'
60
+ require 'morpheus/cli/credentials.rb'
61
61
 
62
- load 'morpheus/cli/cli_command.rb'
63
- load 'morpheus/cli/option_types.rb'
64
- load 'morpheus/cli/credentials.rb'
62
+ # mixins
63
+ Dir[File.dirname(__FILE__) + "/cli/mixins/**/*.rb"].each {|file| require file }
65
64
 
66
- # load all commands
67
- Dir[File.dirname(__FILE__) + "/cli/commands/**/*.rb"].each {|file| load file }
65
+ # commands
66
+ Dir[File.dirname(__FILE__) + "/cli/commands/**/*.rb"].each {|file| require file }
68
67
 
69
68
  end
70
69
 
70
+ # reload! can be used for live reloading changes while developing
71
+ def self.reload!()
72
+ # api interfaces
73
+ Dir[File.dirname(__FILE__) + "/api/**/*.rb"].each { |file| load file }
74
+ # mixins
75
+ Dir[File.dirname(__FILE__) + "/cli/mixins/**/*.rb"].each {|file| load file }
76
+ # commands
77
+ Dir[File.dirname(__FILE__) + "/cli/commands/**/*.rb"].each {|file| load file }
78
+ end
79
+
80
+ # require all CLI modules now (on require)
71
81
  load!
72
82
 
73
83
  end
@@ -5,6 +5,7 @@ require 'rest-client'
5
5
  module RestClient
6
6
  class Request
7
7
 
8
+ alias_method :original_log_request, :log_request
8
9
  def log_request
9
10
  begin
10
11
  return unless RestClient.log
@@ -14,10 +15,10 @@ module RestClient
14
15
  out << payload.short_inspect if payload
15
16
  out << processed_headers.to_a.sort.map { |(k, v)| [k.inspect, v.inspect].join("=>") }.join(", ")
16
17
  RestClient.log << out.join(', ') + "\n"
17
- rescue => ex
18
+ rescue
18
19
  # something went wrong, wrong gem version maybe...above is from rest-client 2.0.2
19
20
  # do it the old way
20
- super
21
+ original_log_request()
21
22
  end
22
23
  end
23
24
  =begin
@@ -1,16 +1,17 @@
1
1
  class String
2
2
 
3
3
  def pluralize
4
+ # hacky version of this until we want to depend on ActiveSupport
4
5
  value = self.dup
5
6
  if value == ""
6
7
  value
7
8
  elsif value[-1].chr == "y"
8
9
  value[0..-2] + "ies"
9
10
  elsif value[-1].chr == "s"
10
- if value[-2..-1] == "es"
11
- value
12
- else
11
+ if value[-2..-1] == "ss"
13
12
  value + "es"
13
+ else
14
+ value
14
15
  end
15
16
  else
16
17
  value + "s"
@@ -18,13 +19,14 @@ class String
18
19
  end
19
20
 
20
21
  def singularize
22
+ # hacky version of this until we want to depend on ActiveSupport
21
23
  value = self.dup
22
24
  if value == ""
23
25
  value
24
26
  elsif value.size > 3 && value[-3..-1] == "ies"
25
27
  value[0..-4] + "y"
26
28
  elsif value.size > 2 && value[-3..-1] == "ses"
27
- value[0..-3]
29
+ value[0..-2]
28
30
  elsif value[-1] == "s"
29
31
  value[0..-2]
30
32
  else
@@ -355,7 +355,7 @@ def format_bytes_short(bytes)
355
355
  end
356
356
 
357
357
  def no_colors(str)
358
- str.to_s.gsub /\e\[\d+m/, ""
358
+ str.to_s.gsub(/\e\[\d+m/, "")
359
359
  end
360
360
 
361
361
 
@@ -85,18 +85,18 @@ module Morpheus::Logging
85
85
  msg = msg.clone
86
86
  # looks for RestClient format (hash.inspect) and request/curl output name: value
87
87
  msg.gsub!(/Authorization\"\s?\=\>\s?\"Bearer [^"]+/i, 'Authorization"=>"Bearer ************')
88
- msg.gsub!(/Authorization\:\s?Bearer [^"'']+/i, 'Authorization: Bearer ************')
88
+ msg.gsub!(/Authorization\:\s?Bearer [^"']+/i, 'Authorization: Bearer ************')
89
89
  # msg.gsub!(/#{AUTHORIZATION_HEADER}\"\s?\=\>\s?\"Bearer [^"]+/, "#{AUTHORIZATION_HEADER}"=>"Bearer ************")
90
- # msg.gsub!(/#{AUTHORIZATION_HEADER}\:\s?Bearer [^"'']+/, "#{AUTHORIZATION_HEADER}: Bearer ************")
90
+ # msg.gsub!(/#{AUTHORIZATION_HEADER}\:\s?Bearer [^"']+/, "#{AUTHORIZATION_HEADER}: Bearer ************")
91
91
  SECRET_TOKEN_HEADERS.each do |header|
92
92
  msg.gsub!(/#{header}\"\s?\=\>\s?\"[^"]+/, "#{header}\"=>\"************")
93
- msg.gsub!(/#{header}\:\s?[^"'']+/, "#{header}: ************")
93
+ msg.gsub!(/#{header}\:\s?[^"']+/, "#{header}: ************")
94
94
  end
95
95
  msg.gsub!(/password\"\: "[^"]+/, 'password": "************') # json properties ending with password
96
96
  msg.gsub!(/Password\"\: "[^"]+/, 'Password": "************') # json properties ending with Password
97
97
  msg.gsub!(/password\"\s?\=\>\s?\"[^"]+/i, 'password"=>"************')
98
98
  msg.gsub!(/password\=\"[^"]+/i, 'password="************')
99
- msg.gsub!(/password\=[^"'&\Z]+/i, 'password=************') # buggy, wont work with ampersand or quotes in passwords! heh
99
+ msg.gsub!(/password\=[^"'&]+/i, 'password=************') # buggy, wont work with ampersand or quotes in passwords! heh
100
100
  msg.gsub!(/passwordConfirmation\=[^" ]+/i, 'passwordConfirmation="************')
101
101
  msg.gsub!(/passwordConfirmation\=[^" ]+/i, 'passwordConfirmation=************')
102
102
  end
@@ -9,7 +9,7 @@ module Morpheus
9
9
  def self.parse_package_manifest(source_directory)
10
10
  source_directory = File.expand_path(source_directory)
11
11
  manifest_filename = File.join(source_directory, "package-manifest.json")
12
- if !File.exists?(manifest_filename)
12
+ if !File.exist?(manifest_filename)
13
13
  raise "Package manifest file not found: #{manifest_filename}"
14
14
  end
15
15
  manifest = JSON.parse(File.read(manifest_filename))
@@ -46,10 +46,10 @@ module Morpheus
46
46
  elsif File.directory?(outfile)
47
47
  outfile = File.join(outfile, "#{code}-#{version}.morpkg")
48
48
  end
49
- if Dir.exists?(outfile)
49
+ if Dir.exist?(outfile)
50
50
  raise "Invalid package target. #{outfile} is the name of an existing directory."
51
51
  end
52
- if File.exists?(outfile)
52
+ if File.exist?(outfile)
53
53
  if do_overwrite
54
54
  # don't delete, just overwrite.
55
55
  # File.delete(outfile)
@@ -58,7 +58,7 @@ module Morpheus
58
58
  end
59
59
  end
60
60
  # build directories if needed
61
- if !Dir.exists?(File.dirname(outfile))
61
+ if !Dir.exist?(File.dirname(outfile))
62
62
  Dir.mkdir(File.dirname(outfile))
63
63
  end
64
64
 
@@ -8,11 +8,11 @@ module Morpheus
8
8
  class << self
9
9
 
10
10
  def user_agent
11
- if !@user_agent
11
+ if !defined?(@user_agent) || @user_agent.nil?
12
12
  begin
13
13
  @user_agent = "morpheus-cli #{Morpheus::Cli::VERSION}"
14
14
  @user_agent = "#{@user_agent} (#{::RestClient::Platform.architecture}) #{::RestClient::Platform.ruby_agent_version}"
15
- rescue => e
15
+ rescue
16
16
  end
17
17
  end
18
18
  return @user_agent
@@ -123,8 +123,8 @@ module Morpheus::Routes
123
123
  admin: {
124
124
  accounts: {}, # Tenants
125
125
  :'service-plans' => [
126
- "#prices",
127
- "#pricesets"
126
+ "#!prices",
127
+ "#!pricesets"
128
128
  ],
129
129
  roles: {},
130
130
  users: {},
@@ -132,7 +132,19 @@ module Morpheus::Routes
132
132
  integrations: {},
133
133
  policies: {},
134
134
  health: ["logs"],
135
- settings: {},
135
+ settings: [
136
+ "#!appliance",
137
+ "#!whitelabel",
138
+ "provisioning",
139
+ "monitoring",
140
+ "backups",
141
+ "logs",
142
+ "#!guidance",
143
+ "environments",
144
+ "software-licenses",
145
+ "#!license",
146
+ "#!utilities"
147
+ ],
136
148
  },
137
149
  :'user-settings' => {}, # User Settings (Profile)
138
150
  } unless defined?(SITE_MAP)
@@ -161,14 +173,34 @@ module Morpheus::Routes
161
173
  # find the one with smallest match index
162
174
 
163
175
  # map well known aliases
164
- case(path.underscore.singularize)
165
- when "server","host","vm","virtual-machine"
176
+ case(path.dasherize.pluralize)
177
+ when "servers","hosts","vms","virtual-machines"
166
178
  # actually should be "/infrastructure/inventory" unless id is passed, show route uses /servers though
167
179
  path = "/infrastructure/servers"
168
- when "compute"
180
+ when "computes", "inventories"
169
181
  path = "/infrastructure/inventory"
170
- when "tenant"
182
+ when "tenants"
171
183
  path = "/admin/accounts"
184
+ when "appliance-settings"
185
+ path = "/admin/settings/#!appliance"
186
+ when "whitelabel-settings"
187
+ path = "/admin/settings/#!whitelabel"
188
+ when "provisioning-settings"
189
+ path = "/admin/settings/#!provisioning"
190
+ when "monitoring-settings","monitor-settings"
191
+ path = "/admin/settings/monitoring"
192
+ when "backup-settings"
193
+ path = "/admin/settings/backups"
194
+ when "log-settings"
195
+ path = "/admin/settings/logs"
196
+ when "guidance-settings"
197
+ path = "/admin/settings/#!guidance"
198
+ when "environments"
199
+ path = "/admin/settings/environments"
200
+ when "software-licenses"
201
+ path = "/admin/settings/software-licenses"
202
+ when "license"
203
+ path = "/admin/settings/#!license"
172
204
  end
173
205
  # dasherize path and attempt to match the plural first
174
206
  plural_path = path.pluralize
@@ -178,7 +210,7 @@ module Morpheus::Routes
178
210
  end
179
211
 
180
212
  best_route = nil
181
- best_index = nil
213
+ #best_index = nil
182
214
  best_prefix_words = nil
183
215
  paths.each do |p|
184
216
  if best_route.nil?
@@ -190,7 +222,7 @@ module Morpheus::Routes
190
222
  #if best_index.nil? || match_index < best_index
191
223
  if best_prefix_words.nil? || prefix_words.size < best_prefix_words.size
192
224
  best_route = it
193
- best_index = match_index
225
+ #best_index = match_index
194
226
  best_prefix_words = prefix_words
195
227
  end
196
228
  end
@@ -1,4 +1,4 @@
1
- require 'morpheus/cli'
1
+ #require 'morpheus/cli' #todo: remove circular require...
2
2
  require 'morpheus/benchmarking'
3
3
  require 'morpheus/logging'
4
4
  require 'morpheus/rest_client'
@@ -7,6 +7,7 @@ require 'morpheus/cli/dot_file'
7
7
  require 'morpheus/cli/error_handler'
8
8
  require 'morpheus/cli/expression_parser'
9
9
  require 'morpheus/cli/option_parser'
10
+ require 'morpheus/cli/version'
10
11
  require 'term/ansicolor'
11
12
 
12
13
  module Morpheus
@@ -41,7 +42,13 @@ module Morpheus
41
42
  include Morpheus::Benchmarking::HasBenchmarking
42
43
  # todo: this can be combined with Cli::Shell
43
44
 
44
- class Blackhole # < IO
45
+ class Blackhole # < File
46
+
47
+ def initialize(*args)
48
+ # we shouldn't actually need a File tho.. but Readline wants one
49
+ # File.open(Morpheus::Cli.windows? ? 'NUL:' : '/dev/null', 'w')
50
+ end
51
+
45
52
  def accrete_data(*mgs)
46
53
  # Singularity.push(*msgs)
47
54
  return nil
@@ -61,7 +68,7 @@ module Morpheus
61
68
  end
62
69
 
63
70
  def self.prompt
64
- if @prompt.nil?
71
+ if !defined?(@prompt) || @prompt.nil?
65
72
  if ENV['MORPHEUS_PS1']
66
73
  @prompt = ENV['MORPHEUS_PS1'].dup
67
74
  else
@@ -91,7 +98,7 @@ module Morpheus
91
98
  # the global Morpheus::Terminal instance
92
99
  # This should go away, but it needed for now...
93
100
  def self.instance
94
- @morphterm # ||= self.new({})
101
+ @morphterm ||= self.new({})
95
102
  end
96
103
 
97
104
  # hack alert! This should go away, but is needed for now...
@@ -112,13 +119,13 @@ module Morpheus
112
119
  # @param stderr [IO] Default is STDERR
113
120
  # @param [IO] stderr
114
121
  # @stderr = stderr
115
- def initialize(stdin=STDIN,stdout=STDOUT, stderr=STDERR, homedir=nil)
122
+ def initialize(stdin=$stdin,stdout=$stdout, stderr=$stderr, homedir=nil)
116
123
  attrs = {}
117
124
  if stdin.is_a?(Hash)
118
125
  attrs = stdin.clone()
119
- stdin = attrs[:stdin] || STDIN
120
- stdout = attrs[:stdout] || STDOUT
121
- stderr = attrs[:stderr] || STDERR
126
+ stdin = attrs[:stdin] || $stdin
127
+ stdout = attrs[:stdout] || $stdout
128
+ stderr = attrs[:stderr] || $stderr
122
129
  homedir = attrs[:homedir] || attrs[:home] || attrs[:home_directory]
123
130
  end
124
131
  # establish IO
@@ -132,12 +139,12 @@ module Morpheus
132
139
  set_home_directory(use_homedir)
133
140
 
134
141
  # use colors by default
135
- set_coloring(STDOUT.isatty)
142
+ set_coloring($stdout.isatty) #rescue nil
136
143
  # Term::ANSIColor::coloring = STDOUT.isatty
137
144
  # @coloring = Term::ANSIColor::coloring?
138
145
 
139
146
  # startup script
140
- if File.exists? Morpheus::Cli::DotFile.morpheus_profile_filename
147
+ if File.exist? Morpheus::Cli::DotFile.morpheus_profile_filename
141
148
  @profile_dot_file = Morpheus::Cli::DotFile.new(Morpheus::Cli::DotFile.morpheus_profile_filename)
142
149
  else
143
150
  @profile_dot_file = nil
@@ -197,13 +204,52 @@ module Morpheus
197
204
  @stderr
198
205
  end
199
206
 
207
+ def with_pipes(opts, &block)
208
+ originals = {} #{stdout: stdout, stderr: stderr, stdin: stdin}
209
+ if opts[:stdout]
210
+ originals[:stdout] = stdout
211
+ set_stdout(opts[:stdout])
212
+ end
213
+ if opts[:stderr]
214
+ originals[:stderr] = stderr
215
+ set_stderr(opts[:stderr])
216
+ end
217
+ if opts[:stdin]
218
+ originals[:stdin] = stdin
219
+ set_stdin(opts[:stdin])
220
+ end
221
+ begin
222
+ yield
223
+ ensure
224
+ set_stdout(originals[:stdout]) if originals[:stdout]
225
+ set_stderr(originals[:stderr]) if originals[:stderr]
226
+ set_stdin(originals[:stdin]) if originals[:stdin]
227
+ end
228
+ end
229
+
230
+ def with_stdout(io, &block)
231
+ with_pipes(stdout:io, &block)
232
+ end
233
+
234
+ def with_stderr(io, &block)
235
+ with_pipes(stderr:io, &block)
236
+ end
237
+
238
+ def with_stdout_and_stderr(io, &block)
239
+ with_pipes(stdout:io, stderr:io, &block)
240
+ end
241
+
242
+ def with_stdin(io, &block)
243
+ with_pipes(stdin:io, &block)
244
+ end
245
+
200
246
  def home_directory=(homedir)
201
247
  set_home_directory(homedir)
202
248
  end
203
249
 
204
250
  def set_home_directory(homedir)
205
251
  full_homedir = File.expand_path(homedir)
206
- # if !Dir.exists?(full_homedir)
252
+ # if !Dir.exist?(full_homedir)
207
253
  # print_red_alert "Directory not found: #{full_homedir}"
208
254
  # exit 1
209
255
  # end
@@ -293,7 +339,7 @@ module Morpheus
293
339
  # out << "Options:\n"
294
340
  out << optparse.to_s
295
341
  out << "\n"
296
- out << "For more information, see https://github.com/gomorpheus/morpheus-cli/wiki"
342
+ out << "For more information, see https://clidocs.morpheusdata.com"
297
343
  out << "\n"
298
344
  out
299
345
  end
@@ -330,6 +376,10 @@ module Morpheus
330
376
  # $stdin.gets(*args)
331
377
  # end
332
378
 
379
+ def readline(*args)
380
+ # todo: one prompt to rule them all
381
+ end
382
+
333
383
  # protected
334
384
 
335
385
  def execute(input)
@@ -397,7 +447,7 @@ module Morpheus
397
447
  set_home_directory(@use_home_directory)
398
448
  # re-initialize some variables
399
449
  # startup script
400
- if File.exists? Morpheus::Cli::DotFile.morpheus_profile_filename
450
+ if File.exist? Morpheus::Cli::DotFile.morpheus_profile_filename
401
451
  @profile_dot_file = Morpheus::Cli::DotFile.new(Morpheus::Cli::DotFile.morpheus_profile_filename)
402
452
  else
403
453
  @profile_dot_file = nil
@@ -414,7 +464,7 @@ module Morpheus
414
464
 
415
465
 
416
466
  if @profile_dot_file && !@profile_dot_file_has_run
417
- if !noprofile && File.exists?(@profile_dot_file.filename)
467
+ if !noprofile && File.exist?(@profile_dot_file.filename)
418
468
  execute_profile_script()
419
469
  end
420
470
  end
@@ -466,14 +516,13 @@ module Morpheus
466
516
  # return 127, nil
467
517
  # end
468
518
 
469
- if @benchmarking || args.include?('-B') || args.include?('--benchmark')
519
+ if (defined?(@benchmarking) && @benchmarking) || args.include?('-B') || args.include?('--benchmark')
470
520
  benchmark_name = "morpheus #{formatted_cmd}"
471
521
  benchmark_name.sub!(' -B', '')
472
522
  benchmark_name.sub!(' --benchmark', '')
473
523
  #benchmark_name << " -B"
474
524
  start_benchmark(benchmark_name)
475
525
  end
476
-
477
526
  # shell is a Singleton command class
478
527
  if args[0] == "shell"
479
528
  require 'morpheus/cli/commands/shell'
data/lib/morpheus.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # This provides the command: require 'morpheus'
2
- # This is really the same as just morpheus/api right now.
2
+ # This is really the same as just morpheus/cli right now.
3
3
  # require 'morpheus/api'
4
4
 
5
5
  require 'morpheus/cli'
data/morpheus-cli.gemspec CHANGED
@@ -29,4 +29,5 @@ Gem::Specification.new do |spec|
29
29
  spec.add_dependency "http"
30
30
  spec.add_dependency "rubyzip"
31
31
  spec.add_dependency "money"
32
+ spec.add_dependency "test-unit"
32
33
  end