morpheus-cli 0.1.1 → 0.9.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.
- checksums.yaml +4 -4
- data/lib/morpheus/api/accounts_interface.rb +55 -0
- data/lib/morpheus/api/api_client.rb +48 -3
- data/lib/morpheus/api/apps_interface.rb +13 -13
- data/lib/morpheus/api/{zones_interface.rb → clouds_interface.rb} +10 -10
- data/lib/morpheus/api/deploy_interface.rb +4 -4
- data/lib/morpheus/api/groups_interface.rb +3 -3
- data/lib/morpheus/api/instance_types_interface.rb +2 -2
- data/lib/morpheus/api/instances_interface.rb +35 -19
- data/lib/morpheus/api/key_pairs_interface.rb +60 -0
- data/lib/morpheus/api/license_interface.rb +29 -0
- data/lib/morpheus/api/load_balancers_interface.rb +72 -0
- data/lib/morpheus/api/logs_interface.rb +37 -0
- data/lib/morpheus/api/options_interface.rb +20 -0
- data/lib/morpheus/api/provision_types_interface.rb +27 -0
- data/lib/morpheus/api/roles_interface.rb +73 -0
- data/lib/morpheus/api/security_group_rules_interface.rb +3 -3
- data/lib/morpheus/api/security_groups_interface.rb +5 -5
- data/lib/morpheus/api/servers_interface.rb +67 -3
- data/lib/morpheus/api/task_sets_interface.rb +46 -0
- data/lib/morpheus/api/tasks_interface.rb +72 -0
- data/lib/morpheus/api/users_interface.rb +72 -0
- data/lib/morpheus/cli.rb +27 -4
- data/lib/morpheus/cli/accounts.rb +306 -0
- data/lib/morpheus/cli/apps.rb +58 -1
- data/lib/morpheus/cli/cli_command.rb +87 -0
- data/lib/morpheus/cli/cli_registry.rb +6 -1
- data/lib/morpheus/cli/{zones.rb → clouds.rb} +99 -70
- data/lib/morpheus/cli/credentials.rb +23 -11
- data/lib/morpheus/cli/error_handler.rb +31 -11
- data/lib/morpheus/cli/groups.rb +1 -0
- data/lib/morpheus/cli/hosts.rb +567 -0
- data/lib/morpheus/cli/instances.rb +588 -292
- data/lib/morpheus/cli/key_pairs.rb +393 -0
- data/lib/morpheus/cli/license.rb +118 -0
- data/lib/morpheus/cli/load_balancers.rb +366 -0
- data/lib/morpheus/cli/mixins/accounts_helper.rb +193 -0
- data/lib/morpheus/cli/option_types.rb +260 -0
- data/lib/morpheus/cli/roles.rb +164 -0
- data/lib/morpheus/cli/security_group_rules.rb +4 -9
- data/lib/morpheus/cli/shell.rb +108 -0
- data/lib/morpheus/cli/tasks.rb +370 -0
- data/lib/morpheus/cli/users.rb +325 -0
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/workflows.rb +100 -0
- data/lib/morpheus/formatters.rb +43 -0
- data/morpheus-cli.gemspec +1 -1
- metadata +33 -10
- data/lib/morpheus/cli/servers.rb +0 -265
@@ -10,24 +10,36 @@ module Morpheus
|
|
10
10
|
@appliance_name = appliance_name
|
11
11
|
end
|
12
12
|
|
13
|
-
def request_credentials()
|
13
|
+
def request_credentials(opts = {})
|
14
|
+
username = nil
|
15
|
+
password = nil
|
16
|
+
creds = nil
|
17
|
+
skip_save = false
|
14
18
|
# We should return an access Key for Morpheus CLI Here
|
15
|
-
|
19
|
+
if !opts[:remote_username].nil?
|
20
|
+
username = opts[:remote_username]
|
21
|
+
password = opts[:remote_password]
|
22
|
+
skip_save = opts[:remote_url] ? true : false
|
23
|
+
else
|
24
|
+
creds = load_saved_credentials
|
25
|
+
end
|
16
26
|
if !creds
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
password
|
22
|
-
|
27
|
+
if username.nil? || username.empty?
|
28
|
+
puts "Enter Username: "
|
29
|
+
username = $stdin.gets.chomp!
|
30
|
+
end
|
31
|
+
if password.nil? || password.empty?
|
32
|
+
puts "Enter Password: "
|
33
|
+
password = STDIN.noecho(&:gets).chomp!
|
34
|
+
end
|
23
35
|
oauth_url = File.join(@appliance_url, "/oauth/token")
|
24
36
|
begin
|
25
|
-
authorize_response = Morpheus::RestClient.post oauth_url, {grant_type: 'password', scope:'write', client_id: 'morph-cli', username: username, password: password}
|
26
|
-
|
37
|
+
authorize_response = Morpheus::RestClient.execute(method: :post, url: oauth_url, headers:{ params: {grant_type: 'password', scope:'write', client_id: 'morph-cli', username: username, password: password}},verify_ssl: false)
|
27
38
|
json_response = JSON.parse(authorize_response.to_s)
|
28
39
|
access_token = json_response['access_token']
|
29
40
|
if access_token
|
30
|
-
|
41
|
+
|
42
|
+
save_credentials(access_token) unless skip_save
|
31
43
|
return access_token
|
32
44
|
else
|
33
45
|
puts "Credentials not verified."
|
@@ -2,23 +2,43 @@ require 'yaml'
|
|
2
2
|
require 'rest_client'
|
3
3
|
require 'term/ansicolor'
|
4
4
|
require 'optparse'
|
5
|
+
require 'json'
|
5
6
|
|
6
7
|
|
7
8
|
class Morpheus::Cli::ErrorHandler
|
8
9
|
include Term::ANSIColor
|
9
10
|
|
10
|
-
def print_errors(response)
|
11
|
-
if
|
12
|
-
print
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
def print_errors(response, options = {})
|
12
|
+
if options[:json]
|
13
|
+
print JSON.pretty_generate(response)
|
14
|
+
else
|
15
|
+
if !response['success']
|
16
|
+
print red,bold, "\n"
|
17
|
+
if response['msg']
|
18
|
+
puts response['msg']
|
19
|
+
end
|
20
|
+
if response['errors']
|
21
|
+
response['errors'].each do |key, value|
|
22
|
+
print "* #{key}: #{value}\n"
|
23
|
+
end
|
19
24
|
end
|
25
|
+
print reset, "\n"
|
20
26
|
end
|
21
|
-
print reset, "\n"
|
22
27
|
end
|
23
28
|
end
|
24
|
-
|
29
|
+
|
30
|
+
def print_rest_exception(e, options={})
|
31
|
+
if e.response.code == 400
|
32
|
+
json_response = JSON.parse(e.response.to_s)
|
33
|
+
if options[:json]
|
34
|
+
print JSON.pretty_generate(json_response)
|
35
|
+
print "\n"
|
36
|
+
else
|
37
|
+
::Morpheus::Cli::ErrorHandler.new.print_errors(json_response)
|
38
|
+
end
|
39
|
+
else
|
40
|
+
puts "Error Communicating with the Appliance. Please try again later. #{e}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
data/lib/morpheus/cli/groups.rb
CHANGED
@@ -0,0 +1,567 @@
|
|
1
|
+
# require 'yaml'
|
2
|
+
require 'io/console'
|
3
|
+
require 'rest_client'
|
4
|
+
require 'term/ansicolor'
|
5
|
+
require 'optparse'
|
6
|
+
require 'morpheus/cli/cli_command'
|
7
|
+
require 'morpheus/cli/option_types'
|
8
|
+
require 'json'
|
9
|
+
|
10
|
+
class Morpheus::Cli::Hosts
|
11
|
+
include Term::ANSIColor
|
12
|
+
include Morpheus::Cli::CliCommand
|
13
|
+
|
14
|
+
def initialize()
|
15
|
+
@appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
16
|
+
@active_groups = ::Morpheus::Cli::Groups.load_group_file
|
17
|
+
end
|
18
|
+
|
19
|
+
def connect(opts)
|
20
|
+
if opts[:remote]
|
21
|
+
@appliance_url = opts[:remote]
|
22
|
+
@appliance_name = opts[:remote]
|
23
|
+
@access_token = Morpheus::Cli::Credentials.new(@appliance_name,@appliance_url).request_credentials(opts)
|
24
|
+
else
|
25
|
+
@access_token = Morpheus::Cli::Credentials.new(@appliance_name,@appliance_url).request_credentials(opts)
|
26
|
+
end
|
27
|
+
@api_client = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url)
|
28
|
+
@clouds_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).clouds
|
29
|
+
@groups_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).groups
|
30
|
+
@tasks_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).tasks
|
31
|
+
@task_sets_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).task_sets
|
32
|
+
@servers_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).servers
|
33
|
+
@logs_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).logs
|
34
|
+
@cloud_types = @clouds_interface.cloud_types['zoneTypes']
|
35
|
+
if @access_token.empty?
|
36
|
+
print red,bold, "\nInvalid Credentials. Unable to acquire access token. Please verify your credentials and try again.\n\n",reset
|
37
|
+
exit 1
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def handle(args)
|
42
|
+
if args.empty?
|
43
|
+
puts "\nUsage: morpheus hosts [list,add,remove,logs,start,stop,run-workflow,make-managed,upgrade-agent] [name]\n\n"
|
44
|
+
exit 1
|
45
|
+
end
|
46
|
+
|
47
|
+
case args[0]
|
48
|
+
when 'list'
|
49
|
+
list(args[1..-1])
|
50
|
+
when 'add'
|
51
|
+
add(args[1..-1])
|
52
|
+
when 'remove'
|
53
|
+
remove(args[1..-1])
|
54
|
+
when 'start'
|
55
|
+
start(args[1..-1])
|
56
|
+
when 'stop'
|
57
|
+
start(args[1..-1])
|
58
|
+
when 'run-workflow'
|
59
|
+
run_workflow(args[1..-1])
|
60
|
+
when 'upgrade-agent'
|
61
|
+
upgrade(args[1..-1])
|
62
|
+
when 'logs'
|
63
|
+
logs(args[1..-1])
|
64
|
+
when 'server-types'
|
65
|
+
server_types(args[1..-1])
|
66
|
+
else
|
67
|
+
puts "\nUsage: morpheus hosts [list,add,remove,logs,start,stop,run-workflow,make-managed,upgrade-agent] [name]\n\n"
|
68
|
+
exit 127 #Command now foud exit code
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def logs(args)
|
73
|
+
options = {}
|
74
|
+
optparse = OptionParser.new do|opts|
|
75
|
+
opts.banner = "Usage: morpheus hosts logs [name]"
|
76
|
+
Morpheus::Cli::CliCommand.genericOptions(opts,options)
|
77
|
+
end
|
78
|
+
if args.count < 1
|
79
|
+
puts "\n#{optparse.banner}\n\n"
|
80
|
+
return
|
81
|
+
end
|
82
|
+
optparse.parse(args)
|
83
|
+
connect(options)
|
84
|
+
begin
|
85
|
+
host = find_host_by_name(args[0])
|
86
|
+
logs = @logs_interface.server_logs([host['id']], { max: options[:max] || 100, offset: options[:offset] || 0, query: options[:phrase]})
|
87
|
+
if options[:json]
|
88
|
+
puts logs
|
89
|
+
else
|
90
|
+
logs['data'].reverse.each do |log_entry|
|
91
|
+
log_level = ''
|
92
|
+
case log_entry['level']
|
93
|
+
when 'INFO'
|
94
|
+
log_level = "#{blue}#{bold}INFO#{reset}"
|
95
|
+
when 'DEBUG'
|
96
|
+
log_level = "#{white}#{bold}DEBUG#{reset}"
|
97
|
+
when 'WARN'
|
98
|
+
log_level = "#{yellow}#{bold}WARN#{reset}"
|
99
|
+
when 'ERROR'
|
100
|
+
log_level = "#{red}#{bold}ERROR#{reset}"
|
101
|
+
when 'FATAL'
|
102
|
+
log_level = "#{red}#{bold}FATAL#{reset}"
|
103
|
+
end
|
104
|
+
puts "[#{log_entry['ts']}] #{log_level} - #{log_entry['message']}"
|
105
|
+
end
|
106
|
+
print reset,"\n"
|
107
|
+
end
|
108
|
+
rescue RestClient::Exception => e
|
109
|
+
::Morpheus::Cli::ErrorHandler.new.print_rest_exception(e)
|
110
|
+
exit 1
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def server_types(args)
|
115
|
+
if args.count < 1
|
116
|
+
puts "\nUsage: morpheus hosts server-types CLOUD\n\n"
|
117
|
+
exit 1
|
118
|
+
end
|
119
|
+
options = {zone: args[0]}
|
120
|
+
|
121
|
+
optparse = OptionParser.new do|opts|
|
122
|
+
opts.banner = "Usage: morpheus server add CLOUD NAME -t HOST_TYPE [options]"
|
123
|
+
opts.on( '-t', '--type TYPE', "Host Type" ) do |server_type|
|
124
|
+
options[:server_type] = server_type
|
125
|
+
end
|
126
|
+
Morpheus::Cli::CliCommand.genericOptions(opts,options)
|
127
|
+
end
|
128
|
+
|
129
|
+
optparse.parse(args)
|
130
|
+
connect(options)
|
131
|
+
params = {}
|
132
|
+
|
133
|
+
zone=nil
|
134
|
+
|
135
|
+
|
136
|
+
if !options[:zone].nil?
|
137
|
+
zone = find_zone_by_name(nil, options[:zone])
|
138
|
+
end
|
139
|
+
|
140
|
+
if zone.nil?
|
141
|
+
puts "Cloud not found"
|
142
|
+
exit 1
|
143
|
+
else
|
144
|
+
zone_type = cloud_type_for_id(zone['zoneTypeId'])
|
145
|
+
end
|
146
|
+
server_types = zone_type['serverTypes'].select{|b| b['creatable'] == true}
|
147
|
+
if options[:json]
|
148
|
+
print JSON.pretty_generate(server_types)
|
149
|
+
print "\n"
|
150
|
+
else
|
151
|
+
|
152
|
+
print "\n" ,red, bold, "Morpheus Server Types\n","==================", reset, "\n\n"
|
153
|
+
if server_types.nil? || server_types.empty?
|
154
|
+
puts yellow,"No server types found for the selected cloud.",reset
|
155
|
+
else
|
156
|
+
server_types.each do |server_type|
|
157
|
+
print red, "= #{server_type['code']} - #{server_type['name']}\n"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
print reset,"\n\n"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def add(args)
|
165
|
+
if args.count < 2
|
166
|
+
puts "\nUsage: morpheus hosts add CLOUD [name]\n\n"
|
167
|
+
return
|
168
|
+
end
|
169
|
+
options = {zone: args[0], params:{}}
|
170
|
+
name = args[1]
|
171
|
+
|
172
|
+
optparse = OptionParser.new do|opts|
|
173
|
+
opts.banner = "Usage: morpheus server add CLOUD NAME -t HOST_TYPE [options]"
|
174
|
+
opts.on( '-t', '--type TYPE', "Host Type" ) do |server_type|
|
175
|
+
options[:server_type] = server_type
|
176
|
+
end
|
177
|
+
Morpheus::Cli::CliCommand.genericOptions(opts,options)
|
178
|
+
end
|
179
|
+
optparse.parse(args)
|
180
|
+
connect(options)
|
181
|
+
|
182
|
+
params = {}
|
183
|
+
|
184
|
+
zone=nil
|
185
|
+
if !options[:zone].nil?
|
186
|
+
zone = find_zone_by_name(nil, options[:zone])
|
187
|
+
options[:params][:zoneId] = zone['id']
|
188
|
+
end
|
189
|
+
|
190
|
+
if zone.nil?
|
191
|
+
puts red,bold,"\nEither the cloud was not specified or was not found. Please make sure a cloud is specied at the beginning of the argument\n\n",reset
|
192
|
+
return
|
193
|
+
else
|
194
|
+
zone_type = cloud_type_for_id(zone['zoneTypeId'])
|
195
|
+
end
|
196
|
+
server_type = zone_type['serverTypes'].find{|b| b['creatable'] == true && (b['code'] == options[:server_type] || b['name'] == options[:server_type])}
|
197
|
+
params = Morpheus::Cli::OptionTypes.prompt(server_type['optionTypes'],options[:options],@api_client, options[:params])
|
198
|
+
begin
|
199
|
+
server_payload = {server: {name: name, zone: {id: zone['id']}, computeServerType: [id: server_type['id']]}.merge(params['server']), config: params['config'], network: params['network']}
|
200
|
+
response = @servers_interface.create(server_payload)
|
201
|
+
rescue RestClient::Exception => e
|
202
|
+
if e.response.code == 400
|
203
|
+
error = JSON.parse(e.response.to_s)
|
204
|
+
::Morpheus::Cli::ErrorHandler.new.print_errors(error)
|
205
|
+
else
|
206
|
+
puts "Error Communicating with the Appliance. Please try again later. #{e}"
|
207
|
+
end
|
208
|
+
exit 1
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def remove(args)
|
213
|
+
if args.count < 1
|
214
|
+
puts "\nUsage: morpheus hosts remove [name] [-c CLOUD] [-f] [-S]\n\n"
|
215
|
+
return
|
216
|
+
end
|
217
|
+
options = {}
|
218
|
+
query_params = {name: args[0], removeResources: 'on', force: 'off'}
|
219
|
+
optparse = OptionParser.new do|opts|
|
220
|
+
opts.on( '-c', '--cloud CLOUD', "Cloud" ) do |cloud|
|
221
|
+
options[:zone] = cloud
|
222
|
+
end
|
223
|
+
opts.on( '-f', '--force', "Force Remove" ) do
|
224
|
+
query_params[:force] = 'on'
|
225
|
+
end
|
226
|
+
opts.on( '-S', '--skip-remove-infrastructure', "Skip removal of underlying cloud infrastructure" ) do
|
227
|
+
query_params[:removeResources] = 'off'
|
228
|
+
end
|
229
|
+
|
230
|
+
Morpheus::Cli::CliCommand.genericOptions(opts,options)
|
231
|
+
end
|
232
|
+
optparse.parse(args)
|
233
|
+
connect(options)
|
234
|
+
zone=nil
|
235
|
+
if !options[:zone].nil?
|
236
|
+
zone = find_zone_by_name(nil, options[:zone])
|
237
|
+
end
|
238
|
+
|
239
|
+
begin
|
240
|
+
|
241
|
+
if zone
|
242
|
+
query_params[:zoneId] = zone['id']
|
243
|
+
end
|
244
|
+
server = nil
|
245
|
+
server_results = @servers_interface.get(query_params)
|
246
|
+
if server_results['servers'].nil? || server_results['servers'].empty?
|
247
|
+
server_results = @servers_interface.get(args[0].to_i)
|
248
|
+
server = server_results['server']
|
249
|
+
else
|
250
|
+
if !server_results['servers'].empty? && server_results['servers'].count > 1
|
251
|
+
puts "Multiple Servers exist with the same name. Try scoping by cloud or using id to confirm"
|
252
|
+
exit 1
|
253
|
+
end
|
254
|
+
server = server_results['servers'][0] unless server_results['servers'].empty?
|
255
|
+
end
|
256
|
+
|
257
|
+
if server.nil?
|
258
|
+
puts "Server not found by name #{args[0]}"
|
259
|
+
exit 1
|
260
|
+
else
|
261
|
+
|
262
|
+
end
|
263
|
+
|
264
|
+
if !::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to remove this server?", options)
|
265
|
+
exit 1
|
266
|
+
end
|
267
|
+
|
268
|
+
json_response = @servers_interface.destroy(server['id'])
|
269
|
+
if options[:json]
|
270
|
+
print JSON.pretty_generate(json_response)
|
271
|
+
print "\n"
|
272
|
+
else
|
273
|
+
puts "Removing Server..."
|
274
|
+
end
|
275
|
+
rescue RestClient::Exception => e
|
276
|
+
if e.response.code == 400
|
277
|
+
error = JSON.parse(e.response.to_s)
|
278
|
+
::Morpheus::Cli::ErrorHandler.new.print_errors(error)
|
279
|
+
else
|
280
|
+
puts "Error Communicating with the Appliance. Please try again later. #{e}"
|
281
|
+
end
|
282
|
+
exit 1
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
def list(args)
|
287
|
+
options = {}
|
288
|
+
params = {}
|
289
|
+
optparse = OptionParser.new do|opts|
|
290
|
+
opts.on( '-g', '--group GROUP', "Group Name" ) do |group|
|
291
|
+
options[:group] = group
|
292
|
+
end
|
293
|
+
|
294
|
+
Morpheus::Cli::CliCommand.genericOptions(opts,options)
|
295
|
+
end
|
296
|
+
optparse.parse(args)
|
297
|
+
connect(options)
|
298
|
+
begin
|
299
|
+
|
300
|
+
if !options[:group].nil?
|
301
|
+
group = find_group_by_name(options[:group])
|
302
|
+
if !group.nil?
|
303
|
+
params['site'] = group['id']
|
304
|
+
end
|
305
|
+
end
|
306
|
+
if !options[:max].nil?
|
307
|
+
params['max'] = options[:max]
|
308
|
+
end
|
309
|
+
if !options[:offset].nil?
|
310
|
+
params['offset'] = options[:offset]
|
311
|
+
end
|
312
|
+
if !options[:phrase].nil?
|
313
|
+
params['phrase'] = options[:phrase]
|
314
|
+
end
|
315
|
+
json_response = @servers_interface.get(params)
|
316
|
+
servers = json_response['servers']
|
317
|
+
if options[:json]
|
318
|
+
print JSON.pretty_generate(json_response)
|
319
|
+
print "\n"
|
320
|
+
else
|
321
|
+
print "\n" ,red, bold, "Morpheus Hosts\n","==================", reset, "\n\n"
|
322
|
+
if servers.empty?
|
323
|
+
puts yellow,"No hosts currently configured.",reset
|
324
|
+
else
|
325
|
+
|
326
|
+
|
327
|
+
server_table =servers.collect do |server|
|
328
|
+
power_state = nil
|
329
|
+
if server['powerState'] == 'on'
|
330
|
+
power_state = "#{green}ON#{red}"
|
331
|
+
elsif server['powerState'] == 'off'
|
332
|
+
power_state = "#{red}OFF#{red}"
|
333
|
+
else
|
334
|
+
power_state = "#{white}#{server['powerState'].upcase}#{red}"
|
335
|
+
end
|
336
|
+
{id: server['id'], name: server['name'], platform: server['serverOs'] ? server['serverOs']['name'].upcase : 'N/A', type: server['computeServerType'] ? server['computeServerType']['name'] : 'unmanaged', status: server['status'], power: power_state}
|
337
|
+
# print red, "= [#{server['id']}] #{server['name']} - #{server['computeServerType'] ? server['computeServerType']['name'] : 'unmanaged'} (#{server['status']}) Power: ", power_state, "\n"
|
338
|
+
end
|
339
|
+
end
|
340
|
+
print red
|
341
|
+
tp server_table, :id, :name, :type, :platform, :status, :power
|
342
|
+
print reset,"\n\n"
|
343
|
+
end
|
344
|
+
rescue => e
|
345
|
+
puts "Error Communicating with the Appliance. Please try again later. #{e}"
|
346
|
+
return nil
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
|
351
|
+
def start(args)
|
352
|
+
options = {}
|
353
|
+
optparse = OptionParser.new do|opts|
|
354
|
+
opts.banner = "Usage: morpheus hosts start [name]"
|
355
|
+
Morpheus::Cli::CliCommand.genericOptions(opts,options)
|
356
|
+
end
|
357
|
+
if args.count < 1
|
358
|
+
puts "\n#{optparse.banner}\n\n"
|
359
|
+
exit 1
|
360
|
+
end
|
361
|
+
optparse.parse(args)
|
362
|
+
connect(options)
|
363
|
+
begin
|
364
|
+
host = find_host_by_name(args[0])
|
365
|
+
json_response = @servers_interface.start(host['id'])
|
366
|
+
if options[:json]
|
367
|
+
print JSON.pretty_generate(json_response)
|
368
|
+
print "\n"
|
369
|
+
else
|
370
|
+
puts "Host #{host[name]} started."
|
371
|
+
end
|
372
|
+
return
|
373
|
+
rescue RestClient::Exception => e
|
374
|
+
::Morpheus::Cli::ErrorHandler.new.print_rest_exception(e)
|
375
|
+
exit 1
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
def stop(args)
|
380
|
+
options = {}
|
381
|
+
optparse = OptionParser.new do|opts|
|
382
|
+
opts.banner = "Usage: morpheus hosts stop [name]"
|
383
|
+
Morpheus::Cli::CliCommand.genericOptions(opts,options)
|
384
|
+
end
|
385
|
+
if args.count < 1
|
386
|
+
puts "\n#{optparse.banner}\n\n"
|
387
|
+
exit 1
|
388
|
+
end
|
389
|
+
optparse.parse(args)
|
390
|
+
connect(options)
|
391
|
+
begin
|
392
|
+
host = find_host_by_name(args[0])
|
393
|
+
json_response = @servers_interface.stop(host['id'])
|
394
|
+
if options[:json]
|
395
|
+
print JSON.pretty_generate(json_response)
|
396
|
+
print "\n"
|
397
|
+
else
|
398
|
+
puts "Host #{host[name]} stopped."
|
399
|
+
end
|
400
|
+
return
|
401
|
+
rescue RestClient::Exception => e
|
402
|
+
::Morpheus::Cli::ErrorHandler.new.print_rest_exception(e)
|
403
|
+
exit 1
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
def upgrade(args)
|
408
|
+
options = {}
|
409
|
+
optparse = OptionParser.new do|opts|
|
410
|
+
opts.banner = "Usage: morpheus hosts upgrade [name]"
|
411
|
+
Morpheus::Cli::CliCommand.genericOptions(opts,options)
|
412
|
+
end
|
413
|
+
if args.count < 1
|
414
|
+
puts "\n#{optparse.banner}\n\n"
|
415
|
+
exit 1
|
416
|
+
end
|
417
|
+
optparse.parse(args)
|
418
|
+
connect(options)
|
419
|
+
begin
|
420
|
+
host = find_host_by_name(args[0])
|
421
|
+
json_response = @servers_interface.upgrade(host['id'])
|
422
|
+
if options[:json]
|
423
|
+
print JSON.pretty_generate(json_response)
|
424
|
+
print "\n"
|
425
|
+
else
|
426
|
+
puts "Host #{host[name]} upgrading..."
|
427
|
+
end
|
428
|
+
return
|
429
|
+
rescue RestClient::Exception => e
|
430
|
+
::Morpheus::Cli::ErrorHandler.new.print_rest_exception(e)
|
431
|
+
exit 1
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
def run_workflow(args)
|
436
|
+
options = {}
|
437
|
+
|
438
|
+
optparse = OptionParser.new do|opts|
|
439
|
+
opts.banner = "Usage: morpheus hosts run-workflow [HOST] [name] [options]"
|
440
|
+
Morpheus::Cli::CliCommand.genericOptions(opts,options)
|
441
|
+
end
|
442
|
+
if args.count < 2
|
443
|
+
puts "\n#{optparse}\n\n"
|
444
|
+
exit 1
|
445
|
+
end
|
446
|
+
|
447
|
+
optparse.parse(args)
|
448
|
+
connect(options)
|
449
|
+
host = find_host_by_name(args[0])
|
450
|
+
workflow = find_workflow_by_name(args[1])
|
451
|
+
task_types = @tasks_interface.task_types()
|
452
|
+
editable_options = []
|
453
|
+
workflow['taskSetTasks'].sort{|a,b| a['taskOrder'] <=> b['taskOrder']}.each do |task_set_task|
|
454
|
+
task_type_id = task_set_task['task']['taskType']['id']
|
455
|
+
task_type = task_types['taskTypes'].find{ |current_task_type| current_task_type['id'] == task_type_id}
|
456
|
+
task_opts = task_type['optionTypes'].select { |otype| otype['editable']}
|
457
|
+
if !task_opts.nil? && !task_opts.empty?
|
458
|
+
editable_options += task_opts.collect do |task_opt|
|
459
|
+
new_task_opt = task_opt.clone
|
460
|
+
new_task_opt['fieldContext'] = "#{task_set_task['id']}.#{new_task_opt['fieldContext']}"
|
461
|
+
end
|
462
|
+
end
|
463
|
+
end
|
464
|
+
params = options[:options] || {}
|
465
|
+
|
466
|
+
if params.empty? && !editable_options.empty?
|
467
|
+
puts "\n#{optparse.banner}\n\n"
|
468
|
+
option_lines = editable_options.collect {|it| "\t-O #{it['fieldContext'] ? (it['fieldContext'] + '.') : ''}#{it['fieldName']}=\"value\"" }.join("\n")
|
469
|
+
puts "\nAvailable Options:\n#{option_lines}\n\n"
|
470
|
+
exit 1
|
471
|
+
end
|
472
|
+
|
473
|
+
workflow_payload = {taskSet: {"#{workflow['id']}": params }}
|
474
|
+
begin
|
475
|
+
|
476
|
+
json_response = @servers_interface.workflow(host['id'],workflow['id'], workflow_payload)
|
477
|
+
if options[:json]
|
478
|
+
print JSON.pretty_generate(json_response)
|
479
|
+
print "\n"
|
480
|
+
else
|
481
|
+
puts "Running workflow..."
|
482
|
+
end
|
483
|
+
rescue RestClient::Exception => e
|
484
|
+
::Morpheus::Cli::ErrorHandler.new.print_rest_exception(e)
|
485
|
+
exit 1
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
private
|
490
|
+
|
491
|
+
def find_host_by_name(name)
|
492
|
+
server = nil
|
493
|
+
server_results = @servers_interface.get({name: name})
|
494
|
+
if server_results['servers'].nil? || server_results['servers'].empty?
|
495
|
+
server_results = @servers_interface.get(name.to_i)
|
496
|
+
server = server_results['server']
|
497
|
+
else
|
498
|
+
if !server_results['servers'].empty? && server_results['servers'].count > 1
|
499
|
+
puts "Multiple Servers exist with the same name. Try using id to confirm"
|
500
|
+
exit 1
|
501
|
+
end
|
502
|
+
server = server_results['servers'][0] unless server_results['servers'].empty?
|
503
|
+
end
|
504
|
+
|
505
|
+
if server.nil?
|
506
|
+
puts "Server not found by name #{args[0]}"
|
507
|
+
exit 1
|
508
|
+
end
|
509
|
+
return server
|
510
|
+
end
|
511
|
+
def find_group_by_name(name)
|
512
|
+
group_results = @groups_interface.get(name)
|
513
|
+
if group_results['groups'].empty?
|
514
|
+
puts "Group not found by name #{name}"
|
515
|
+
return nil
|
516
|
+
end
|
517
|
+
return group_results['groups'][0]
|
518
|
+
end
|
519
|
+
|
520
|
+
def find_zone_by_name(groupId, name)
|
521
|
+
zone_results = @clouds_interface.get({groupId: groupId, name: name})
|
522
|
+
if zone_results['zones'].empty?
|
523
|
+
puts "Zone not found by name #{name}"
|
524
|
+
return nil
|
525
|
+
end
|
526
|
+
return zone_results['zones'][0]
|
527
|
+
end
|
528
|
+
|
529
|
+
def find_server_type(zone, name)
|
530
|
+
server_type = zone['serverTypes'].select do |sv_type|
|
531
|
+
(sv_type['name'].downcase == name.downcase || sv_type['code'].downcase == name.downcase) && sv_type['creatable'] == true
|
532
|
+
end
|
533
|
+
if server_type.nil?
|
534
|
+
puts "Server Type Not Selectable"
|
535
|
+
end
|
536
|
+
return server_type
|
537
|
+
end
|
538
|
+
|
539
|
+
def cloud_type_for_id(id)
|
540
|
+
if !@cloud_types.empty?
|
541
|
+
zone_type = @cloud_types.find { |z| z['id'].to_i == id.to_i}
|
542
|
+
if !zone_type.nil?
|
543
|
+
return zone_type
|
544
|
+
end
|
545
|
+
end
|
546
|
+
return nil
|
547
|
+
end
|
548
|
+
|
549
|
+
def find_workflow_by_name(name)
|
550
|
+
task_set_results = @task_sets_interface.get(name)
|
551
|
+
if !task_set_results['taskSets'].nil? && !task_set_results['taskSets'].empty?
|
552
|
+
return task_set_results['taskSets'][0]
|
553
|
+
else
|
554
|
+
puts "Workflow not found by name #{name}"
|
555
|
+
exit 1
|
556
|
+
end
|
557
|
+
end
|
558
|
+
|
559
|
+
def find_group_by_id(id)
|
560
|
+
group_results = @groups_interface.get(id)
|
561
|
+
if group_results['groups'].empty?
|
562
|
+
puts "Group not found by id #{id}"
|
563
|
+
return nil
|
564
|
+
end
|
565
|
+
return group_results['groups'][0]
|
566
|
+
end
|
567
|
+
end
|