morpheus-cli 5.5.2.2 → 5.5.3.1

Sign up to get free protection for your applications and to get access to all the features.
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