morpheus-cli 2.10.1 → 2.10.2
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.
- checksums.yaml +4 -4
- data/bin/morpheus +60 -21
- data/lib/morpheus/api/api_client.rb +2 -0
- data/lib/morpheus/api/instances_interface.rb +8 -0
- data/lib/morpheus/cli.rb +19 -10
- data/lib/morpheus/cli/accounts.rb +32 -9
- data/lib/morpheus/cli/alias_command.rb +68 -22
- data/lib/morpheus/cli/app_templates.rb +22 -7
- data/lib/morpheus/cli/apps.rb +32 -26
- data/lib/morpheus/cli/cli_command.rb +135 -27
- data/lib/morpheus/cli/clouds.rb +8 -3
- data/lib/morpheus/cli/coloring_command.rb +39 -0
- data/lib/morpheus/cli/dot_file.rb +207 -0
- data/lib/morpheus/cli/echo_command.rb +32 -0
- data/lib/morpheus/cli/error_handler.rb +3 -1
- data/lib/morpheus/cli/groups.rb +18 -20
- data/lib/morpheus/cli/hosts.rb +96 -22
- data/lib/morpheus/cli/instances.rb +76 -8
- data/lib/morpheus/cli/log_level_command.rb +51 -0
- data/lib/morpheus/cli/option_parser.rb +13 -7
- data/lib/morpheus/cli/option_types.rb +337 -317
- data/lib/morpheus/cli/remote.rb +37 -6
- data/lib/morpheus/cli/roles.rb +3 -1
- data/lib/morpheus/cli/shell.rb +299 -245
- data/lib/morpheus/cli/source_command.rb +39 -0
- data/lib/morpheus/cli/ssl_verification_command.rb +49 -0
- data/lib/morpheus/cli/tasks.rb +2 -2
- data/lib/morpheus/cli/users.rb +7 -11
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/virtual_images.rb +3 -4
- data/lib/morpheus/cli/whoami.rb +6 -5
- data/morpheus-cli.gemspec +1 -1
- data/scripts/generate_morpheus_commands_help.morpheus +1253 -0
- metadata +10 -3
- data/lib/morpheus/cli/config_file.rb +0 -126
@@ -0,0 +1,207 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'time'
|
3
|
+
require 'morpheus/cli/cli_registry'
|
4
|
+
require 'morpheus/logging'
|
5
|
+
require 'term/ansicolor'
|
6
|
+
|
7
|
+
class Morpheus::Cli::DotFile
|
8
|
+
include Term::ANSIColor
|
9
|
+
|
10
|
+
DEFAULT_EXEC_PROC = lambda {|args|
|
11
|
+
|
12
|
+
}
|
13
|
+
EXPORTED_ALIASES_HEADER = "# exported aliases"
|
14
|
+
|
15
|
+
# the path of the profile source file
|
16
|
+
# this is executed when `morpheus` is run
|
17
|
+
def self.morpheus_profile_filename
|
18
|
+
File.join(Morpheus::Cli.home_directory, ".morpheus_profile")
|
19
|
+
end
|
20
|
+
|
21
|
+
# the path of the shell source file
|
22
|
+
# this is executed when `morpheus shell` is run
|
23
|
+
def self.morpheusrc_filename
|
24
|
+
File.join(Morpheus::Cli.home_directory, ".morpheusrc")
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_reader :filename
|
28
|
+
attr_reader :file_contents
|
29
|
+
attr_reader :commands
|
30
|
+
attr_reader :cmd_results
|
31
|
+
|
32
|
+
def initialize(fn)
|
33
|
+
@filename = fn
|
34
|
+
#load_file()
|
35
|
+
end
|
36
|
+
|
37
|
+
# execute this file as a morpheus shell script
|
38
|
+
# @param stop_on_failure [true, false] the will halt execution if a command returns false.
|
39
|
+
# Default is false, keep going...
|
40
|
+
# @block [Proc] if a block is given, each command in the file will be yielded to it
|
41
|
+
# The default is executes the command with the CliRegistry.exec(cmd, args)
|
42
|
+
# @return [Array] exit codes of all the commands that were run.
|
43
|
+
def execute(stop_on_failure=false, &block)
|
44
|
+
if !File.exists?(@filename)
|
45
|
+
print "#{Term::ANSIColor.red}source file not found: #{@filename}#{Term::ANSIColor.reset}\n" # if Morpheus::Logging.debug?
|
46
|
+
else
|
47
|
+
print "#{dark} #=> executing source file #{@filename}#{reset}\n" if Morpheus::Logging.debug?
|
48
|
+
end
|
49
|
+
file_contents ||= File.read(@filename)
|
50
|
+
lines = file_contents.split("\n")
|
51
|
+
cmd_results = []
|
52
|
+
line_num = 0
|
53
|
+
lines.each_with_index do |line, line_index|
|
54
|
+
line_num = line_index + 1
|
55
|
+
line = line.strip
|
56
|
+
next if line.empty?
|
57
|
+
next if line =~ /^\#/ # skip comments
|
58
|
+
|
59
|
+
# print "#{dark} #=> executing source file line #{line_num}: #{line}#{reset}\n" if Morpheus::Logging.debug?
|
60
|
+
|
61
|
+
# todo: allow semicolons inside arguments too..
|
62
|
+
command_list = line.strip.split(';').compact
|
63
|
+
command_list.each do |input|
|
64
|
+
input = input.strip
|
65
|
+
if input.empty?
|
66
|
+
next
|
67
|
+
end
|
68
|
+
argv = Shellwords.shellsplit(input)
|
69
|
+
|
70
|
+
if Morpheus::Cli::CliRegistry.has_command?(argv[0]) || Morpheus::Cli::CliRegistry.has_alias?(argv[0])
|
71
|
+
#log_history_command(input)
|
72
|
+
cmd_result = nil
|
73
|
+
begin
|
74
|
+
cmd_result = Morpheus::Cli::CliRegistry.exec(argv[0], argv[1..-1])
|
75
|
+
rescue SystemExit => err
|
76
|
+
if err.success?
|
77
|
+
cmd_result = true
|
78
|
+
else
|
79
|
+
puts "#{red} source file: #{@filename} line: #{line_num} command: #{argv[0]}#{reset} error: exited non zero - #{err}"
|
80
|
+
cmd_result = false
|
81
|
+
end
|
82
|
+
rescue => err
|
83
|
+
# raise err
|
84
|
+
puts "#{red} source file: #{@filename} line: #{line_num} command: #{argv[0]}#{reset} error: unexpected error - #{err}"
|
85
|
+
cmd_result = false
|
86
|
+
end
|
87
|
+
cmd_results << cmd_result
|
88
|
+
# next command please!
|
89
|
+
else
|
90
|
+
puts "#{red}Unrecognized source command file: #{@filename} line: #{line_num} command: #{argv[0]}#{reset}"
|
91
|
+
cmd_result = false
|
92
|
+
end
|
93
|
+
if cmd_result == false
|
94
|
+
if stop_on_failure
|
95
|
+
return cmd_results
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
return cmd_results
|
102
|
+
end
|
103
|
+
|
104
|
+
# this saves the source file, upserting alias definitions at the bottom
|
105
|
+
# todo: smarter logic to allow the user to put stuff AFTER this section too
|
106
|
+
# under the section titled '# exported aliases'
|
107
|
+
# @param alias_definitions [Map] Map of alias_name => command_string
|
108
|
+
# @return nil
|
109
|
+
def export_aliases(alias_definitions)
|
110
|
+
if !@filename
|
111
|
+
print "#{Term::ANSIColor.dark}Skipping source file save because filename has not been set#{Term::ANSIColor.reset}\n" if Morpheus::Logging.debug?
|
112
|
+
return false
|
113
|
+
end
|
114
|
+
if !Dir.exists?(File.dirname(@filename))
|
115
|
+
FileUtils.mkdir_p(File.dirname(@filename))
|
116
|
+
end
|
117
|
+
if !File.exists?(@filename)
|
118
|
+
print "#{Term::ANSIColor.dark}Initializing source file #{@filename}#{Term::ANSIColor.reset}\n" if Morpheus::Logging.debug?
|
119
|
+
FileUtils.touch(@filename)
|
120
|
+
else
|
121
|
+
print "#{dark} #=> Saving source file #{@filename}#{reset}\n" if Morpheus::Logging.debug?
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
config_text = File.read(@filename)
|
126
|
+
config_lines = config_text.split(/\n/)
|
127
|
+
new_config_lines = []
|
128
|
+
existing_alias_definitions = {}
|
129
|
+
header_line_index = config_lines.index {|line| line.strip.include?(EXPORTED_ALIASES_HEADER) }
|
130
|
+
if header_line_index
|
131
|
+
# keep everything before the exported alias section
|
132
|
+
new_config_lines = config_lines[0..header_line_index-1]
|
133
|
+
existing_alias_lines = config_lines[header_line_index..config_lines.size-1]
|
134
|
+
# parse out the existing alias definitions
|
135
|
+
existing_alias_lines.each do |line|
|
136
|
+
if line =~ /^alias\s+/
|
137
|
+
alias_name, command_string = Morpheus::Cli::CliRegistry.parse_alias_definition(line)
|
138
|
+
if alias_name.empty? || command_string.empty?
|
139
|
+
print "#{dark} #=> removing bad config line #{line_num} invalid alias definition: #{line}\n" if Morpheus::Logging.debug?
|
140
|
+
else
|
141
|
+
existing_alias_definitions[alias_name] = command_string
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
else
|
146
|
+
new_config_lines = config_lines
|
147
|
+
new_config_lines << "" # blank line before alias header
|
148
|
+
end
|
149
|
+
|
150
|
+
# append header line
|
151
|
+
new_config_lines << EXPORTED_ALIASES_HEADER
|
152
|
+
new_config_lines << "# Do not put anything below here, or it will be lost when aliases are exported"
|
153
|
+
#new_config_lines << ""
|
154
|
+
|
155
|
+
# update aliases, sort them, and append the lines
|
156
|
+
new_alias_definitions = existing_alias_definitions.merge(alias_definitions)
|
157
|
+
new_alias_definitions.keys.sort.each do |alias_name|
|
158
|
+
new_config_lines << "alias #{alias_name}='#{new_alias_definitions[alias_name]}'"
|
159
|
+
end
|
160
|
+
|
161
|
+
# include a blank line after this section
|
162
|
+
new_config_lines << ""
|
163
|
+
new_config_lines << ""
|
164
|
+
|
165
|
+
new_config_text = new_config_lines.join("\n")
|
166
|
+
|
167
|
+
File.open(@filename, 'w') {|f| f.write(new_config_text) }
|
168
|
+
return true
|
169
|
+
end
|
170
|
+
|
171
|
+
# this saves the source file, removing alias definitions at the bottom
|
172
|
+
# todo: smarter logic to allow the user to put stuff AFTER this section too
|
173
|
+
# under the section titled '# exported aliases'
|
174
|
+
# @param alias_definitions [Map] Map of alias_name => command_string
|
175
|
+
# @return nil
|
176
|
+
def remove_aliases(alias_names)
|
177
|
+
if !@filename
|
178
|
+
print "#{Term::ANSIColor.dark}Skipping source file save because filename has not been set#{Term::ANSIColor.reset}\n" if Morpheus::Logging.debug?
|
179
|
+
return false
|
180
|
+
end
|
181
|
+
if !Dir.exists?(File.dirname(@filename))
|
182
|
+
FileUtils.mkdir_p(File.dirname(@filename))
|
183
|
+
end
|
184
|
+
if !File.exists?(@filename)
|
185
|
+
print "#{Term::ANSIColor.dark}Initializing source file #{@filename}#{Term::ANSIColor.reset}\n" if Morpheus::Logging.debug?
|
186
|
+
FileUtils.touch(@filename)
|
187
|
+
else
|
188
|
+
print "#{dark} #=> Saving source file #{@filename}#{reset}\n" if Morpheus::Logging.debug?
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
config_text = File.read(@filename)
|
193
|
+
config_lines = config_text.split(/\n/)
|
194
|
+
|
195
|
+
new_config_lines = config_lines.reject {|line|
|
196
|
+
alias_names.find {|alias_name| /^alias\s+#{Regexp.escape(alias_name)}\s?\=/ }
|
197
|
+
}
|
198
|
+
|
199
|
+
new_config_text = new_config_lines.join("\n")
|
200
|
+
|
201
|
+
File.open(@filename, 'w') {|f| f.write(new_config_text) }
|
202
|
+
return true
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
|
207
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'morpheus/cli/cli_command'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
# This is for use in dotfile scripts
|
6
|
+
class Morpheus::Cli::EchoCommand
|
7
|
+
include Morpheus::Cli::CliCommand
|
8
|
+
set_command_name :echo
|
9
|
+
set_command_hidden
|
10
|
+
|
11
|
+
def handle(args)
|
12
|
+
append_newline = true
|
13
|
+
options = {}
|
14
|
+
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
15
|
+
opts.banner = "Usage: morpheus #{command_name} [<message>]"
|
16
|
+
opts.on( '-n', '--nonewline', "do not append a newline to your words" ) do
|
17
|
+
append_newline = false
|
18
|
+
end
|
19
|
+
build_common_options(opts, options, [])
|
20
|
+
end
|
21
|
+
optparse.parse!(args)
|
22
|
+
out = ""
|
23
|
+
out << args.join(' ')
|
24
|
+
if append_newline
|
25
|
+
out << "\n"
|
26
|
+
end
|
27
|
+
# print out
|
28
|
+
print cyan + out + reset
|
29
|
+
return true
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -12,12 +12,14 @@ class Morpheus::Cli::ErrorHandler
|
|
12
12
|
end
|
13
13
|
case (err)
|
14
14
|
when OptionParser::InvalidOption, OptionParser::AmbiguousOption, OptionParser::MissingArgument, OptionParser::InvalidArgument
|
15
|
-
# raise
|
15
|
+
# raise err
|
16
16
|
print_red_alert "#{err.message}"
|
17
17
|
puts "Try -h for help with this command."
|
18
18
|
when Errno::ECONNREFUSED
|
19
19
|
print_red_alert "#{err.message}"
|
20
20
|
# more special errors?
|
21
|
+
when OpenSSL::SSL::SSLError
|
22
|
+
print_red_alert "Error Communicating with the Appliance. #{err.message}"
|
21
23
|
when RestClient::Exception
|
22
24
|
print_rest_exception(err, options)
|
23
25
|
else
|
data/lib/morpheus/cli/groups.rb
CHANGED
@@ -128,12 +128,14 @@ class Morpheus::Cli::Groups
|
|
128
128
|
use_it = false
|
129
129
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
130
130
|
opts.banner = subcommand_usage("[name]")
|
131
|
-
opts
|
132
|
-
|
133
|
-
|
131
|
+
build_option_type_options(opts, options, add_group_option_types())
|
132
|
+
# opts.on( '-l', '--location LOCATION', "Location" ) do |val|
|
133
|
+
# params[:location] = val
|
134
|
+
# end
|
134
135
|
opts.on( '--use', '--use', "Make this the current active group" ) do
|
135
136
|
use_it = true
|
136
137
|
end
|
138
|
+
|
137
139
|
build_common_options(opts, options, [:options, :json, :dry_run, :remote])
|
138
140
|
opts.footer = "Create a new group."
|
139
141
|
end
|
@@ -187,9 +189,10 @@ class Morpheus::Cli::Groups
|
|
187
189
|
params = {}
|
188
190
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
189
191
|
opts.banner = subcommand_usage("[name] [options]")
|
190
|
-
opts
|
191
|
-
|
192
|
-
|
192
|
+
build_option_type_options(opts, options, update_group_option_types())
|
193
|
+
# opts.on( '-l', '--location LOCATION', "Location" ) do |val|
|
194
|
+
# params[:location] = val
|
195
|
+
# end
|
193
196
|
build_common_options(opts, options, [:options, :json, :dry_run, :remote])
|
194
197
|
opts.footer = "Update an existing group."
|
195
198
|
end
|
@@ -203,13 +206,11 @@ class Morpheus::Cli::Groups
|
|
203
206
|
group = find_group_by_name_or_id(args[0])
|
204
207
|
group_payload = {id: group['id']}
|
205
208
|
|
206
|
-
|
207
|
-
#params = Morpheus::Cli::OptionTypes.prompt(all_option_types, options[:options], @api_client, {})
|
209
|
+
#params = Morpheus::Cli::OptionTypes.prompt(update_group_option_types, options[:options], @api_client, {})
|
208
210
|
params = options[:options] || {}
|
209
211
|
|
210
212
|
if params.empty?
|
211
|
-
puts optparse
|
212
|
-
print_available_options(all_option_types)
|
213
|
+
puts optparse
|
213
214
|
exit 1
|
214
215
|
end
|
215
216
|
|
@@ -364,8 +365,8 @@ class Morpheus::Cli::Groups
|
|
364
365
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
365
366
|
opts.banner = subcommand_usage("[name]")
|
366
367
|
opts.footer = "" +
|
367
|
-
"This sets the
|
368
|
-
"
|
368
|
+
"This sets the active group.\n" +
|
369
|
+
"The active group will be auto-selected for use during provisioning.\n" +
|
369
370
|
"You can still use the --group option to override this."
|
370
371
|
build_common_options(opts, options, [])
|
371
372
|
end
|
@@ -401,9 +402,10 @@ class Morpheus::Cli::Groups
|
|
401
402
|
def unuse(args)
|
402
403
|
options = {}
|
403
404
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
404
|
-
opts.banner = subcommand_usage()
|
405
|
-
|
406
|
-
"
|
405
|
+
opts.banner = subcommand_usage()
|
406
|
+
opts.footer = "" +
|
407
|
+
"This will clear the current active group.\n" +
|
408
|
+
"You will be prompted for a Group during provisioning."
|
407
409
|
build_common_options(opts, options, [])
|
408
410
|
end
|
409
411
|
optparse.parse!(args)
|
@@ -429,10 +431,7 @@ class Morpheus::Cli::Groups
|
|
429
431
|
optparse = Morpheus::Cli::OptionParser.new do|opts|
|
430
432
|
opts.banner = subcommand_usage()
|
431
433
|
build_common_options(opts, options, [])
|
432
|
-
opts.footer = ""
|
433
|
-
"This will set the current remote appliance.\n" +
|
434
|
-
"It will be used for all subsequent commands.\n" +
|
435
|
-
"You may still use the --remote option to override this."
|
434
|
+
opts.footer = "Prints the name of the current active group"
|
436
435
|
end
|
437
436
|
optparse.parse!(args)
|
438
437
|
connect(options)
|
@@ -509,7 +508,6 @@ public
|
|
509
508
|
end
|
510
509
|
|
511
510
|
# Provides the current active group information (just the ID right now)
|
512
|
-
# appliance_name should probably be required.. or just use this instead: Groups.active_groups[appliance_name]
|
513
511
|
def active_group(appliance_name=nil)
|
514
512
|
if appliance_name == nil
|
515
513
|
appliance_name, appliance_url = Morpheus::Cli::Remote.active_appliance
|
data/lib/morpheus/cli/hosts.rb
CHANGED
@@ -10,7 +10,7 @@ require 'json'
|
|
10
10
|
class Morpheus::Cli::Hosts
|
11
11
|
include Morpheus::Cli::CliCommand
|
12
12
|
include Morpheus::Cli::ProvisioningHelper
|
13
|
-
register_subcommands :list, :get, :stats, :add, :remove, :logs, :start, :stop, :resize, :run_workflow, :
|
13
|
+
register_subcommands :list, :get, :stats, :add, :remove, :logs, :start, :stop, :resize, :run_workflow, {:'make-managed' => :install_agent}, :upgrade_agent, :server_types
|
14
14
|
alias_subcommand :details, :get
|
15
15
|
set_default_subcommand :list
|
16
16
|
|
@@ -147,6 +147,11 @@ class Morpheus::Cli::Hosts
|
|
147
147
|
puts "Type: #{server['computeServerType'] ? server['computeServerType']['name'] : 'unmanaged'}"
|
148
148
|
puts "Platform: #{server['serverOs'] ? server['serverOs']['name'].upcase : 'N/A'}"
|
149
149
|
puts "Plan: #{server['plan'] ? server['plan']['name'] : ''}"
|
150
|
+
if server['agentInstalled']
|
151
|
+
puts "Agent: #{server['agentVersion'] || ''} updated at #{format_local_dt(server['lastAgentUpdate'])}"
|
152
|
+
else
|
153
|
+
puts "Agent: (not installed)"
|
154
|
+
end
|
150
155
|
puts "Status: #{format_host_status(server)}"
|
151
156
|
puts "Power: #{format_server_power_state(server)}"
|
152
157
|
if ((stats['maxMemory'].to_i != 0) || (stats['maxStorage'].to_i != 0))
|
@@ -325,7 +330,7 @@ class Morpheus::Cli::Hosts
|
|
325
330
|
opts.on( '-t', '--type TYPE', "Server Type Code" ) do |val|
|
326
331
|
options[:server_type_code] = val
|
327
332
|
end
|
328
|
-
build_common_options(opts, options, [:options, :json, :dry_run, :remote])
|
333
|
+
build_common_options(opts, options, [:options, :json, :dry_run, :quiet, :remote])
|
329
334
|
end
|
330
335
|
optparse.parse!(args)
|
331
336
|
connect(options)
|
@@ -457,8 +462,8 @@ class Morpheus::Cli::Hosts
|
|
457
462
|
if options[:json]
|
458
463
|
print JSON.pretty_generate(json_response)
|
459
464
|
print "\n"
|
460
|
-
|
461
|
-
print_green_success "Provisioning Server..."
|
465
|
+
elsif !options[:quiet]
|
466
|
+
print_green_success "Provisioning Server..."
|
462
467
|
list([])
|
463
468
|
end
|
464
469
|
rescue RestClient::Exception => e
|
@@ -478,7 +483,7 @@ class Morpheus::Cli::Hosts
|
|
478
483
|
opts.on( '-S', '--skip-remove-infrastructure', "Skip removal of underlying cloud infrastructure" ) do
|
479
484
|
query_params[:removeResources] = 'off'
|
480
485
|
end
|
481
|
-
build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
|
486
|
+
build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :quiet, :remote])
|
482
487
|
end
|
483
488
|
optparse.parse!(args)
|
484
489
|
if args.count < 1
|
@@ -500,9 +505,9 @@ class Morpheus::Cli::Hosts
|
|
500
505
|
if options[:json]
|
501
506
|
print JSON.pretty_generate(json_response)
|
502
507
|
print "\n"
|
503
|
-
|
504
|
-
print_green_success "
|
505
|
-
list([])
|
508
|
+
elsif !options[:quiet]
|
509
|
+
print_green_success "Host #{server['name']} is being removed..."
|
510
|
+
#list([])
|
506
511
|
end
|
507
512
|
rescue RestClient::Exception => e
|
508
513
|
print_rest_exception(e, options)
|
@@ -514,7 +519,7 @@ class Morpheus::Cli::Hosts
|
|
514
519
|
options = {}
|
515
520
|
optparse = OptionParser.new do|opts|
|
516
521
|
opts.banner = subcommand_usage("[name]")
|
517
|
-
build_common_options(opts, options, [:json, :remote])
|
522
|
+
build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
|
518
523
|
end
|
519
524
|
optparse.parse!(args)
|
520
525
|
if args.count < 1
|
@@ -524,12 +529,16 @@ class Morpheus::Cli::Hosts
|
|
524
529
|
connect(options)
|
525
530
|
begin
|
526
531
|
host = find_host_by_name_or_id(args[0])
|
532
|
+
if options[:dry_run]
|
533
|
+
print_dry_run @servers_interface.dry.start(host['id'])
|
534
|
+
return
|
535
|
+
end
|
527
536
|
json_response = @servers_interface.start(host['id'])
|
528
537
|
if options[:json]
|
529
538
|
print JSON.pretty_generate(json_response)
|
530
539
|
print "\n"
|
531
|
-
|
532
|
-
|
540
|
+
elsif !options[:quiet]
|
541
|
+
print_green_success "Host #{host['name']} started."
|
533
542
|
end
|
534
543
|
return
|
535
544
|
rescue RestClient::Exception => e
|
@@ -542,7 +551,7 @@ class Morpheus::Cli::Hosts
|
|
542
551
|
options = {}
|
543
552
|
optparse = OptionParser.new do|opts|
|
544
553
|
opts.banner = subcommand_usage("[name]")
|
545
|
-
build_common_options(opts, options, [:json, :remote])
|
554
|
+
build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
|
546
555
|
end
|
547
556
|
optparse.parse!(args)
|
548
557
|
if args.count < 1
|
@@ -560,8 +569,8 @@ class Morpheus::Cli::Hosts
|
|
560
569
|
if options[:json]
|
561
570
|
print JSON.pretty_generate(json_response)
|
562
571
|
print "\n"
|
563
|
-
|
564
|
-
puts "Host #{host['name']} stopped."
|
572
|
+
elsif !options[:quiet]
|
573
|
+
puts "Host #{host['name']} stopped."
|
565
574
|
end
|
566
575
|
return
|
567
576
|
rescue RestClient::Exception => e
|
@@ -654,7 +663,7 @@ class Morpheus::Cli::Hosts
|
|
654
663
|
print "\n"
|
655
664
|
else
|
656
665
|
unless options[:quiet]
|
657
|
-
|
666
|
+
puts "Host #{server['name']} resizing..."
|
658
667
|
list([])
|
659
668
|
end
|
660
669
|
end
|
@@ -664,11 +673,63 @@ class Morpheus::Cli::Hosts
|
|
664
673
|
end
|
665
674
|
end
|
666
675
|
|
667
|
-
def
|
676
|
+
def install_agent(args)
|
677
|
+
options = {}
|
678
|
+
optparse = OptionParser.new do|opts|
|
679
|
+
opts.banner = subcommand_usage("[name]")
|
680
|
+
build_option_type_options(opts, options, install_agent_option_types(false))
|
681
|
+
build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
|
682
|
+
end
|
683
|
+
optparse.parse!(args)
|
684
|
+
if args.count < 1
|
685
|
+
puts optparse
|
686
|
+
exit 1
|
687
|
+
end
|
688
|
+
connect(options)
|
689
|
+
begin
|
690
|
+
host = find_host_by_name_or_id(args[0])
|
691
|
+
if host['agentInstalled']
|
692
|
+
print_red_alert "Agent already installed on host '#{host['name']}'"
|
693
|
+
return false
|
694
|
+
end
|
695
|
+
payload = {
|
696
|
+
'server' => {}
|
697
|
+
}
|
698
|
+
params = Morpheus::Cli::OptionTypes.prompt(install_agent_option_types, options[:options], @api_client, options[:params])
|
699
|
+
server_os = params.delete('serverOs')
|
700
|
+
if server_os
|
701
|
+
payload['server']['serverOs'] = {id: server_os}
|
702
|
+
end
|
703
|
+
account_id = params.delete('account') # not yet implemented
|
704
|
+
if account_id
|
705
|
+
payload['server']['account'] = {id: account}
|
706
|
+
end
|
707
|
+
payload['server'].merge!(params)
|
708
|
+
|
709
|
+
if options[:dry_run]
|
710
|
+
print_dry_run @servers_interface.dry.install_agent(host['id'], payload)
|
711
|
+
return
|
712
|
+
end
|
713
|
+
json_response = @servers_interface.install_agent(host['id'], payload)
|
714
|
+
if options[:json]
|
715
|
+
print JSON.pretty_generate(json_response)
|
716
|
+
print "\n"
|
717
|
+
elsif !options[:quiet]
|
718
|
+
print_green_success "Host #{host['name']} is being converted to managed."
|
719
|
+
puts "Public Key:\n#{json_response['publicKey']}\n(copy to your authorized_keys file)"
|
720
|
+
end
|
721
|
+
return true
|
722
|
+
rescue RestClient::Exception => e
|
723
|
+
print_rest_exception(e, options)
|
724
|
+
exit 1
|
725
|
+
end
|
726
|
+
end
|
727
|
+
|
728
|
+
def upgrade_agent(args)
|
668
729
|
options = {}
|
669
730
|
optparse = OptionParser.new do|opts|
|
670
731
|
opts.banner = subcommand_usage("[name]")
|
671
|
-
build_common_options(opts, options, [:json, :quiet, :remote])
|
732
|
+
build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
|
672
733
|
end
|
673
734
|
optparse.parse!(args)
|
674
735
|
if args.count < 1
|
@@ -678,6 +739,10 @@ class Morpheus::Cli::Hosts
|
|
678
739
|
connect(options)
|
679
740
|
begin
|
680
741
|
host = find_host_by_name_or_id(args[0])
|
742
|
+
if options[:dry_run]
|
743
|
+
print_dry_run @servers_interface.dry.upgrade(host['id'])
|
744
|
+
return
|
745
|
+
end
|
681
746
|
json_response = @servers_interface.upgrade(host['id'])
|
682
747
|
if options[:json]
|
683
748
|
print JSON.pretty_generate(json_response)
|
@@ -696,13 +761,13 @@ class Morpheus::Cli::Hosts
|
|
696
761
|
options = {}
|
697
762
|
optparse = OptionParser.new do|opts|
|
698
763
|
opts.banner = subcommand_usage("run-workflow", "[name]", "[workflow]")
|
699
|
-
build_common_options(opts, options, [:json, :dry_run, :remote])
|
764
|
+
build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
|
700
765
|
end
|
766
|
+
optparse.parse!(args)
|
701
767
|
if args.count < 2
|
702
|
-
puts
|
768
|
+
puts optparse
|
703
769
|
exit 1
|
704
770
|
end
|
705
|
-
optparse.parse!(args)
|
706
771
|
connect(options)
|
707
772
|
host = find_host_by_name_or_id(args[0])
|
708
773
|
workflow = find_workflow_by_name(args[1])
|
@@ -738,8 +803,8 @@ class Morpheus::Cli::Hosts
|
|
738
803
|
if options[:json]
|
739
804
|
print JSON.pretty_generate(json_response)
|
740
805
|
print "\n"
|
741
|
-
|
742
|
-
puts "
|
806
|
+
elsif !options[:quiet]
|
807
|
+
puts "Workflow #{workflow['name']} is running..."
|
743
808
|
end
|
744
809
|
rescue RestClient::Exception => e
|
745
810
|
print_rest_exception(e, options)
|
@@ -873,4 +938,13 @@ class Morpheus::Cli::Hosts
|
|
873
938
|
out
|
874
939
|
end
|
875
940
|
|
941
|
+
def install_agent_option_types(connected=true)
|
942
|
+
[
|
943
|
+
#{'fieldName' => 'account', 'fieldLabel' => 'Account', 'type' => 'select', 'optionSource' => 'accounts', 'required' => true},
|
944
|
+
{'fieldName' => 'sshUsername', 'fieldLabel' => 'SSH Username', 'type' => 'text', 'required' => true},
|
945
|
+
{'fieldName' => 'sshPassword', 'fieldLabel' => 'SSH Password', 'type' => 'password', 'required' => false},
|
946
|
+
{'fieldName' => 'serverOs', 'fieldLabel' => 'OS Type', 'type' => 'select', 'optionSource' => 'osTypes', 'required' => false},
|
947
|
+
]
|
948
|
+
end
|
949
|
+
|
876
950
|
end
|