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