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