morpheus-cli 2.10.3 → 2.11.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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/bin/morpheus +5 -96
  3. data/lib/morpheus/api/api_client.rb +23 -1
  4. data/lib/morpheus/api/checks_interface.rb +106 -0
  5. data/lib/morpheus/api/incidents_interface.rb +102 -0
  6. data/lib/morpheus/api/monitoring_apps_interface.rb +47 -0
  7. data/lib/morpheus/api/monitoring_contacts_interface.rb +47 -0
  8. data/lib/morpheus/api/monitoring_groups_interface.rb +47 -0
  9. data/lib/morpheus/api/monitoring_interface.rb +36 -0
  10. data/lib/morpheus/api/option_type_lists_interface.rb +47 -0
  11. data/lib/morpheus/api/option_types_interface.rb +47 -0
  12. data/lib/morpheus/api/roles_interface.rb +0 -1
  13. data/lib/morpheus/api/setup_interface.rb +19 -9
  14. data/lib/morpheus/cli.rb +20 -1
  15. data/lib/morpheus/cli/accounts.rb +8 -3
  16. data/lib/morpheus/cli/app_templates.rb +19 -11
  17. data/lib/morpheus/cli/apps.rb +52 -37
  18. data/lib/morpheus/cli/cli_command.rb +229 -53
  19. data/lib/morpheus/cli/cli_registry.rb +48 -40
  20. data/lib/morpheus/cli/clouds.rb +55 -26
  21. data/lib/morpheus/cli/command_error.rb +12 -0
  22. data/lib/morpheus/cli/credentials.rb +68 -26
  23. data/lib/morpheus/cli/curl_command.rb +98 -0
  24. data/lib/morpheus/cli/dashboard_command.rb +2 -7
  25. data/lib/morpheus/cli/deployments.rb +4 -4
  26. data/lib/morpheus/cli/deploys.rb +1 -2
  27. data/lib/morpheus/cli/dot_file.rb +5 -8
  28. data/lib/morpheus/cli/error_handler.rb +179 -15
  29. data/lib/morpheus/cli/groups.rb +21 -13
  30. data/lib/morpheus/cli/hosts.rb +220 -110
  31. data/lib/morpheus/cli/instance_types.rb +2 -2
  32. data/lib/morpheus/cli/instances.rb +257 -167
  33. data/lib/morpheus/cli/key_pairs.rb +15 -9
  34. data/lib/morpheus/cli/library.rb +673 -27
  35. data/lib/morpheus/cli/license.rb +2 -2
  36. data/lib/morpheus/cli/load_balancers.rb +4 -4
  37. data/lib/morpheus/cli/log_level_command.rb +6 -4
  38. data/lib/morpheus/cli/login.rb +17 -3
  39. data/lib/morpheus/cli/logout.rb +25 -11
  40. data/lib/morpheus/cli/man_command.rb +388 -0
  41. data/lib/morpheus/cli/mixins/accounts_helper.rb +1 -1
  42. data/lib/morpheus/cli/mixins/monitoring_helper.rb +434 -0
  43. data/lib/morpheus/cli/mixins/print_helper.rb +620 -112
  44. data/lib/morpheus/cli/mixins/provisioning_helper.rb +1 -1
  45. data/lib/morpheus/cli/monitoring_apps_command.rb +29 -0
  46. data/lib/morpheus/cli/monitoring_checks_command.rb +427 -0
  47. data/lib/morpheus/cli/monitoring_contacts_command.rb +373 -0
  48. data/lib/morpheus/cli/monitoring_groups_command.rb +29 -0
  49. data/lib/morpheus/cli/monitoring_incidents_command.rb +711 -0
  50. data/lib/morpheus/cli/option_types.rb +10 -1
  51. data/lib/morpheus/cli/recent_activity_command.rb +2 -5
  52. data/lib/morpheus/cli/remote.rb +874 -134
  53. data/lib/morpheus/cli/roles.rb +54 -27
  54. data/lib/morpheus/cli/security_group_rules.rb +2 -2
  55. data/lib/morpheus/cli/security_groups.rb +23 -19
  56. data/lib/morpheus/cli/set_prompt_command.rb +50 -0
  57. data/lib/morpheus/cli/shell.rb +222 -157
  58. data/lib/morpheus/cli/tasks.rb +19 -15
  59. data/lib/morpheus/cli/users.rb +27 -17
  60. data/lib/morpheus/cli/version.rb +1 -1
  61. data/lib/morpheus/cli/virtual_images.rb +28 -13
  62. data/lib/morpheus/cli/whoami.rb +131 -52
  63. data/lib/morpheus/cli/workflows.rb +24 -9
  64. data/lib/morpheus/formatters.rb +195 -3
  65. data/lib/morpheus/logging.rb +86 -0
  66. data/lib/morpheus/terminal.rb +371 -0
  67. data/scripts/generate_morpheus_commands_help.morpheus +60 -0
  68. metadata +21 -2
@@ -45,7 +45,7 @@ class Morpheus::Cli::License
45
45
  puts "No License Currently Applied to the appliance."
46
46
  exit 1
47
47
  else
48
- print "\n", cyan, "License\n=======\n"
48
+ print_h1 "License"
49
49
  max_memory = Filesize.from("#{license['license']['maxMemory']} B").pretty
50
50
  max_storage = Filesize.from("#{license['license']['maxStorage']} B").pretty
51
51
  used_memory = Filesize.from("#{license['usedMemory']} B").pretty
@@ -77,7 +77,7 @@ class Morpheus::Cli::License
77
77
  key = args[0]
78
78
  else
79
79
  v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'licenseKey', 'fieldLabel' => 'License Key', 'type' => 'text', 'required' => true}], options[:options])
80
- instance_name = v_prompt['licenseKey'] || ''
80
+ key = v_prompt['licenseKey'] || ''
81
81
  end
82
82
  if options[:dry_run]
83
83
  print_dry_run @license_interface.dry.apply(key)
@@ -47,9 +47,9 @@ class Morpheus::Cli::LoadBalancers
47
47
  print JSON.pretty_generate(json_response)
48
48
  else
49
49
  lbs = json_response['loadBalancers']
50
- print "\n" ,cyan, bold, "Morpheus Load Balancers\n","==================", reset, "\n\n"
50
+ print_h1 "Morpheus Load Balancers"
51
51
  if lbs.empty?
52
- puts yellow,"No load balancers currently configured.",reset
52
+ print cyan,"No load balancers found.",reset,"\n"
53
53
  else
54
54
  print cyan
55
55
  lb_table_data = lbs.collect do |lb|
@@ -186,9 +186,9 @@ class Morpheus::Cli::LoadBalancers
186
186
  print JSON.pretty_generate(json_response)
187
187
  else
188
188
  lb_types = json_response['loadBalancerTypes']
189
- print "\n" ,cyan, bold, "Morpheus Load Balancer Types\n","============================", reset, "\n\n"
189
+ print_h1 "Morpheus Load Balancer Types"
190
190
  if lb_types.nil? || lb_types.empty?
191
- puts yellow,"No lb types currently exist on this appliance. This could be a seed issue.",reset
191
+ print yellow,"No lb types currently exist on this appliance. This could be a seed issue.",reset,"\n"
192
192
  else
193
193
  print cyan
194
194
  lb_table_data = lb_types.collect do |lb_type|
@@ -1,6 +1,7 @@
1
1
  require 'optparse'
2
- require 'morpheus/cli/cli_command'
3
2
  require 'json'
3
+ require 'morpheus/logging'
4
+ require 'morpheus/cli/cli_command'
4
5
 
5
6
  class Morpheus::Cli::LogLevelCommand
6
7
  include Morpheus::Cli::CliCommand
@@ -34,13 +35,14 @@ EOT
34
35
  end
35
36
  if ["debug", "0"].include?(args[0].to_s.strip.downcase)
36
37
  Morpheus::Logging.set_log_level(Morpheus::Logging::Logger::DEBUG)
37
- ::RestClient.log = Morpheus::Logging.debug? ? STDOUT : nil
38
+ ::RestClient.log = Morpheus::Logging.debug? ? Morpheus::Logging::DarkPrinter.instance : nil
39
+ Morpheus::Logging::DarkPrinter.puts "debug enabled"
38
40
  elsif ["info", "1"].include?(args[0].to_s.strip.downcase)
39
41
  Morpheus::Logging.set_log_level(Morpheus::Logging::Logger::INFO)
40
- ::RestClient.log = Morpheus::Logging.debug? ? STDOUT : nil
42
+ ::RestClient.log = Morpheus::Logging.debug? ? Morpheus::Logging::DarkPrinter.instance : nil
41
43
  elsif args[0].to_i < 6
42
44
  Morpheus::Logging.set_log_level(args[0].to_i)
43
- ::RestClient.log = Morpheus::Logging.debug? ? STDOUT : nil
45
+ ::RestClient.log = Morpheus::Logging.debug? ? Morpheus::Logging::DarkPrinter.instance : nil
44
46
  else
45
47
  puts optparse
46
48
  return false
@@ -49,7 +49,7 @@ class Morpheus::Cli::Login
49
49
  @appliance_name, @appliance_url = nil, nil
50
50
  end
51
51
  if !@appliance_name
52
- print_red_alert "You have no appliance named '#{options[:remote]}' configured. See the `remote add` command."
52
+ print_red_alert "You have no appliance named '#{options[:remote]}' configured. See the `remote list` command."
53
53
  return false
54
54
  end
55
55
  else
@@ -70,11 +70,25 @@ class Morpheus::Cli::Login
70
70
  options[:remote_username] = username if username
71
71
  options[:remote_password] = password if password
72
72
  #options[:remote_url] = true # will skip credentials save
73
- Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).login(options)
73
+ login_result = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).login(options)
74
+
75
+ # check to see if we got credentials, or just look at login_result above...
76
+ creds = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).load_saved_credentials() # .load_saved_credentials(true)
77
+
78
+ # recalculate shell prompt after this change
79
+ if Morpheus::Cli::Shell.instance
80
+ Morpheus::Cli::Shell.instance.reinitialize()
81
+ end
82
+
83
+ if creds
84
+ return 0 # , nil
85
+ else
86
+ return 1 # , "Login failed"
87
+ end
74
88
 
75
89
  rescue RestClient::Exception => e
76
90
  print_rest_exception(e, options)
77
- exit 1
91
+ return 1
78
92
  end
79
93
 
80
94
  end
@@ -32,28 +32,42 @@ class Morpheus::Cli::Logout
32
32
  options = {}
33
33
  optparse = OptionParser.new do|opts|
34
34
  opts.banner = usage
35
- build_common_options(opts, options, [:remote]) # todo: support :remote too perhaps
35
+ build_common_options(opts, options, [:remote, :quiet])
36
36
  end
37
37
  optparse.parse!(args)
38
- connect(options)
38
+ # connect(options)
39
+ # establish @appliance_name, @appliance_url,
40
+ @api_client = establish_remote_appliance_connection(options.merge({:no_prompt => true, :skip_verify_access_token => true}))
39
41
 
40
42
  begin
41
43
  if !@appliance_name
42
- print yellow,"Please specify a Morpheus Appliance to logout of with -r or see the command `remote use`#{reset}\n"
43
- return
44
+ print_error Morpheus::Terminal.angry_prompt
45
+ puts_error "Please specify a Morpheus Appliance to logout of with -r or see the command `remote use`"
46
+ return 1
44
47
  end
45
- creds = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).load_saved_credentials()
46
- if !creds
47
- print yellow,"You are not currently logged in to #{display_appliance(@appliance_name, @appliance_url)}\n",reset
48
- return 0
48
+ creds = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url)
49
+ token = creds.saved_credentials
50
+ if !token
51
+ if !options[:quiet]
52
+ puts "You are not currently logged in to #{display_appliance(@appliance_name, @appliance_url)}"
53
+ end
49
54
  else
55
+ # todo: need to tell the server to delete the token too..
56
+ # delete token from credentials file
57
+ # note: this also handles updating appliance session info
50
58
  Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).logout()
51
- print cyan,"Goodbye\n",reset
59
+ if !options[:quiet]
60
+ puts "#{cyan}Logged out of #{@appliance_name}. Goodbye.#{reset}"
61
+ end
52
62
  end
53
-
63
+ # recalculate shell prompt after this change
64
+ if Morpheus::Cli::Shell.instance
65
+ Morpheus::Cli::Shell.instance.reinitialize()
66
+ end
67
+ return 0
54
68
  rescue RestClient::Exception => e
55
69
  print_rest_exception(e, options)
56
- return 1
70
+ return false
57
71
  end
58
72
 
59
73
  end
@@ -0,0 +1,388 @@
1
+ require 'optparse'
2
+ require 'morpheus/logging'
3
+ require 'morpheus/cli/cli_command'
4
+
5
+ class Morpheus::Cli::ManCommand
6
+ include Morpheus::Cli::CliCommand
7
+ set_command_name :man
8
+ set_command_hidden
9
+
10
+ # this should be read only anyway...
11
+ @@default_editor = "less" # ENV['EDITOR']
12
+
13
+ def handle(args)
14
+ options = {}
15
+ regenerate = false
16
+ editor = @@default_editor
17
+ open_as_link = false # true please
18
+ goto_wiki = false
19
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
20
+ opts.banner = "Usage: morpheus man"
21
+ opts.on('-w','--wiki', "Open the morpheus-cli wiki instead of the local man page") do
22
+ goto_wiki = true
23
+ end
24
+ opts.on('-e','--editor EDITOR', "Specify which program to open the manual with. Default is '#{editor}'.") do |val|
25
+ editor = val
26
+ open_as_link = false
27
+ end
28
+ opts.on('-g','--generate', "Regenerate the manual file") do
29
+ regenerate = true
30
+ end
31
+ opts.on('-q','--quiet', "Do not open manual, for use with the -g option.") do
32
+ options[:quiet] = true
33
+ end
34
+ #build_common_options(opts, options, [:quiet])
35
+ # disable ANSI coloring
36
+ opts.on('-C','--nocolor', "Disable ANSI coloring") do
37
+ Term::ANSIColor::coloring = false
38
+ end
39
+
40
+ opts.on('-V','--debug', "Print extra output for debugging. ") do
41
+ Morpheus::Logging.set_log_level(Morpheus::Logging::Logger::DEBUG)
42
+ ::RestClient.log = Morpheus::Logging.debug? ? Morpheus::Logging::DarkPrinter.instance : nil
43
+ end
44
+ opts.on('-h', '--help', "Prints this help" ) do
45
+ puts opts
46
+ exit
47
+ end
48
+ opts.footer = <<-EOT
49
+ Open the morpheus manual located at #{Morpheus::Cli::ManCommand.man_file_path}
50
+ The -g switch be used to regenerate the file.
51
+ EOT
52
+ end
53
+ optparse.parse!(args)
54
+
55
+ if goto_wiki
56
+ link = "https://github.com/gomorpheus/morpheus-cli/wiki/CLI-Manual"
57
+ if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
58
+ system "start #{link}"
59
+ elsif RbConfig::CONFIG['host_os'] =~ /darwin/
60
+ system "open #{link}"
61
+ elsif RbConfig::CONFIG['host_os'] =~ /linux|bsd/
62
+ system "xdg-open #{link}"
63
+ end
64
+ return 0, nil
65
+ end
66
+
67
+ fn = Morpheus::Cli::ManCommand.man_file_path
68
+ if regenerate || !File.exists?(fn)
69
+ #Morpheus::Logging::DarkPrinter.puts "generating manual #{fn} ..." if Morpheus::Logging.debug?
70
+ Morpheus::Cli::ManCommand.generate_manual()
71
+ end
72
+
73
+ if options[:quiet]
74
+ return 0, nil
75
+ end
76
+
77
+ Morpheus::Logging::DarkPrinter.puts "opening manual file #{fn}" if Morpheus::Logging.debug?
78
+
79
+
80
+ if open_as_link # not used atm
81
+ link = "file://#{fn}"
82
+ if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
83
+ system "start #{link}"
84
+ elsif RbConfig::CONFIG['host_os'] =~ /darwin/
85
+ system "open #{link}"
86
+ elsif RbConfig::CONFIG['host_os'] =~ /linux|bsd/
87
+ system "xdg-open #{link}"
88
+ end
89
+ return 0, nil
90
+ else
91
+ if editor
92
+ if !system_command_available?(editor)
93
+ raise_command_error "The editor program '#{editor}' is not available on your system."
94
+ # puts_error "#{red}The editor program '#{editor}' is not available on your system.#{reset}"
95
+ # return 1
96
+ end
97
+ system("#{editor} #{fn}")
98
+ else
99
+ raise_command_error "Tell me how to open the manual file #{fn}. Try -e emacs or run export EDITOR=emacs"
100
+ return 1
101
+ end
102
+ end
103
+
104
+ return 0, nil
105
+ end
106
+
107
+ # determine if system command is available
108
+ # uses *nix's `which` command.
109
+ # Prevents using dangerous commands rm,mv,passwd
110
+ # todo: support for Windows and PowerShell
111
+ def system_command_available?(cmd)
112
+ has_it = false
113
+ begin
114
+ cmd = cmd.strip
115
+ if cmd.include?(';') ||
116
+ cmd =~ /^rm/ || cmd.strip =~ /^mv/ || cmd.strip =~ /^passwd/ ||
117
+ cmd.include?("/rm") || cmd.include?("/mv") || cmd.include?("/passwd")
118
+ raise_command_error "The specified system command '#{cmd}' is invalid."
119
+ end
120
+ system("which #{cmd} > /dev/null 2>&1")
121
+ has_it = $?.success?
122
+ rescue => e
123
+ raise e
124
+ end
125
+ return has_it
126
+ end
127
+
128
+ def self.man_file_path
129
+ File.join(Morpheus::Cli.home_directory, "CLI-Manual-#{Morpheus::Cli::VERSION}.md")
130
+ end
131
+
132
+ # def self.save_manual(fn, content)
133
+ # # fn = man_file_path()
134
+ # if !Dir.exists?(File.dirname(fn))
135
+ # FileUtils.mkdir_p(File.dirname(fn))
136
+ # end
137
+ # Morpheus::Logging::DarkPrinter.puts "saving manual to #{fn}" if Morpheus::Logging.debug?
138
+ # File.open(fn, 'w') {|f| f.write content.to_s } #Store
139
+ # FileUtils.chmod(0600, fn)
140
+ # end
141
+
142
+ def self.generate_manual()
143
+ # todo: use pandoc or something else to convert the CLI-Manual.md to a man page
144
+ # and install it, so the os command `man morpheus` will work too.
145
+ fn = man_file_path()
146
+ if !Dir.exists?(File.dirname(fn))
147
+ FileUtils.mkdir_p(File.dirname(fn))
148
+ end
149
+ Morpheus::Logging::DarkPrinter.puts "generating manual #{fn}" if Morpheus::Logging.debug?
150
+
151
+ File.open(fn, 'w') {|f| f.write("") } # clear file
152
+ FileUtils.chmod(0600, fn)
153
+
154
+ manpage = File.new(fn, 'w')
155
+ previous_stdout = $stdout
156
+ $stdout = manpage
157
+ begin
158
+
159
+ $stdout.print <<-ENDTEXT
160
+ ## NAME
161
+
162
+ morpheus - the command line interface for interacting with the Morpheus Data appliance
163
+
164
+ ## SYNOPSIS
165
+
166
+ morpheus [command] [<args>]
167
+
168
+ ## DESCRIPTION
169
+
170
+ Morpheus CLI
171
+
172
+ This is a command line interface for managing a Morpheus Appliance.
173
+ All communication with the remote appliance is done via the Morpheus API.
174
+
175
+ To setup a new appliance, see the `remote add` and `remote setup` commands.
176
+
177
+ To get started, visit https://github.com/gomorpheus/morpheus-cli/wiki/Getting-Started
178
+
179
+ To learn more about the Morpheus Appliance, visit https://www.morpheusdata.com/features
180
+
181
+ To learn more about the Morpheus API, visit http://bertramdev.github.io/morpheus-apidoc/
182
+
183
+ ## GLOBAL OPTIONS
184
+
185
+ Morpheus supports a few global options.
186
+
187
+ -v, --version Print the version.
188
+ --noprofile Do not read and execute the personal initialization script .morpheus_profile
189
+ -C, --nocolor Disable ANSI coloring
190
+ -V, --debug Print extra output for debugging.
191
+ -h, --help Prints this help
192
+
193
+ ## COMMON OPTIONS
194
+
195
+ There are some common options that many commands support. They work the same way for each command.
196
+
197
+ -O, --option OPTION Option value in the format -O var="value" (deprecated soon in favor of first class options)
198
+ -N, --no-prompt Skip prompts. Use default values for all optional fields.
199
+ -j, --json JSON Output
200
+ -d, --dry-run Dry Run, print the API request instead of executing it
201
+ -r, --remote REMOTE Remote Appliance Name to use for this command. The active appliance is used by default.
202
+ -I, --insecure Allow for insecure HTTPS communication i.e. bad SSL certificate
203
+ -y, --yes Auto confirm, skip any 'Are you sure?' confirmations.
204
+ -r, --quiet No Output, when successful.
205
+
206
+ ## MORPHEUS COMMANDS
207
+
208
+ We divide morpheus into commands.
209
+ Every morpheus command may have 0-N sub-commands that it supports.
210
+ Commands generally map to the functionality provided in the Morpheus UI.
211
+
212
+ You can get help for any morpheus command by using the -h option.
213
+
214
+ The available commands and their options are also documented below.
215
+ ENDTEXT
216
+
217
+ terminal = Morpheus::Terminal.new($stdin, $stdout)
218
+ Morpheus::Logging::DarkPrinter.puts "appending command help `morpheus --help`" if Morpheus::Logging.debug?
219
+
220
+ $stdout.print "\n"
221
+ $stdout.print "## morpheus\n"
222
+ $stdout.print "\n"
223
+ $stdout.print "```\n"
224
+ exit_code, err = terminal.execute("--help")
225
+ $stdout.print "```\n"
226
+ $stdout.print "\n"
227
+ # output help for every unhidden command
228
+ Morpheus::Cli::CliRegistry.all.keys.sort.each do |cmd|
229
+ cmd_klass = Morpheus::Cli::CliRegistry.instance.get(cmd)
230
+ cmd_instance = cmd_klass.new
231
+ Morpheus::Logging::DarkPrinter.puts "appending command help `morpheus #{cmd} --help`" if Morpheus::Logging.debug?
232
+ #help_cmd = "morpheus #{cmd} --help"
233
+ #help_output = `#{help_cmd}`
234
+ $stdout.print "\n"
235
+ $stdout.print "### morpheus #{cmd}\n"
236
+ $stdout.print "\n"
237
+ $stdout.print "```\n"
238
+ begin
239
+ cmd_instance.handle(["--help"])
240
+ rescue SystemExit => err
241
+ raise err unless err.success?
242
+ end
243
+ $stdout.print "```\n"
244
+ subcommands = cmd_klass.subcommands
245
+ if subcommands && subcommands.size > 0
246
+ subcommands.sort.each do |subcommand, subcommand_method|
247
+ Morpheus::Logging::DarkPrinter.puts "appending command help `morpheus #{cmd} #{subcommand} --help`" if Morpheus::Logging.debug?
248
+ $stdout.print "\n"
249
+ $stdout.print "#### morpheus #{cmd} #{subcommand}\n"
250
+ $stdout.print "\n"
251
+ $stdout.print "```\n"
252
+ begin
253
+ cmd_instance.handle([subcommand, "--help"])
254
+ rescue SystemExit => err
255
+ raise err unless err.success?
256
+ end
257
+ $stdout.print "```\n"
258
+ # $stdout.print "\n"
259
+ end
260
+ end
261
+ $stdout.print "\n"
262
+ end
263
+
264
+ $stdout.print <<-ENDTEXT
265
+
266
+ ## ENVIRONMENT VARIABLES
267
+
268
+ Morpheus has only one environment variable that it uses.
269
+
270
+ ### MORPHEUS_CLI_HOME
271
+
272
+ The **MORPHEUS_CLI_HOME** variable is where morpheus CLI stores its configuration files.
273
+ This can be set to allow a single system user to maintain many different configurations
274
+ If the directory does not exist, morpheus will attempt to create it.
275
+
276
+ The default home directory is **$HOME/.morpheus**
277
+
278
+ To see how this works, run the following:
279
+
280
+ ```shell
281
+ MORPHEUS_CLI_HOME=~/.morpheus_test morpheus shell
282
+ ```
283
+
284
+ Now, in your new morpheus shell, you can see that it is a fresh environment.
285
+ There are no remote appliances configured.
286
+
287
+ ```shell
288
+ morpheus> remote list
289
+
290
+ Morpheus Appliances
291
+ ==================
292
+
293
+ You have no appliances configured. See the `remote add` command.
294
+
295
+ ```
296
+
297
+ You can use this to create isolated environments (sandboxes), within which to execute your morpheus commands.
298
+
299
+ ```shell
300
+ export MORPHEUS_CLI_HOME=~/morpheus_test
301
+ morpheus remote add myremote https://testmorpheusappliance.mycompany.com --insecure
302
+ morpheus instances list
303
+ ```
304
+
305
+ Morpheus saves the remote appliance information, including api access tokens,
306
+ to the $MORPHEUS_HOME_DIRECTORY. These files are saved with file permissions **6000**.
307
+ So, only one system user should be allowed to execute morpheus with that home directory.
308
+ See [Configuration](#Configuration) for more information on the files morpheus reads and writes.
309
+
310
+ ## CONFIGURATION
311
+
312
+ Morpheus reads and writes several configuration files within the $MORPHEUS_CLI_HOME directory.
313
+
314
+ **Note:** These files are maintained by the program. It is not recommended for you to manipulate them.
315
+
316
+ ### appliances file
317
+
318
+ The `appliances` YAML file contains a list of known appliances, keyed by name.
319
+
320
+ Example:
321
+ ```yaml
322
+ :qa:
323
+ :host: https://qa.mycoolsite.com
324
+ :active: true
325
+ :production:
326
+ :host: https://morpheus.mycoolsite.com
327
+ :active: false
328
+ ```
329
+
330
+ ### credentials file
331
+
332
+ The `.morpheus/credentials` YAML file contains access tokens for each known appliance.
333
+
334
+ ### groups file
335
+
336
+ The `.morpheus/groups` YAML file contains the active group information for each known appliance.
337
+
338
+
339
+ ## Startup scripts
340
+
341
+ When Morpheus starts, it executes the commands in a couple of dot files.
342
+
343
+ These scripts are written in morpheus commands, not bash, so they can only execute morpheus commands and aliases.
344
+
345
+ ### .morpheus_profile file
346
+
347
+ It looks for `$MORPHEUS_CLI_HOME/.morpheus_profile`, and reads and executes it (if it exists).
348
+
349
+ This may be inhibited by using the `--noprofile` option.
350
+
351
+ ### .morpheusrc file
352
+
353
+ When started as an interactive shell with the `morpheus shell` command,
354
+ Morpheus reads and executes `$MORPHEUS_CLI_HOME/.morpheusrc` (if it exists). This may be inhibited by using the `--norc` option.
355
+
356
+ An example startup script might look like this:
357
+
358
+ ```
359
+ # .morpheusrc
360
+
361
+ # aliases
362
+ alias our-instances='instances list -c "Our Cloud"'
363
+
364
+ # switch to our appliance that we created with `remote add morphapp1`
365
+ remote use morphapp1
366
+
367
+ # greeting
368
+ echo "Welcome back human, have fun!"
369
+
370
+ # print current user information
371
+ whoami
372
+
373
+ # print the list of instances in our cloud
374
+ our-instances
375
+
376
+ ```
377
+
378
+ ENDTEXT
379
+
380
+ ensure
381
+ manpage.close if manpage
382
+ $stdout = previous_stdout if previous_stdout
383
+ end
384
+
385
+ return true
386
+ end
387
+
388
+ end