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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/lib/morpheus/api/accounts_interface.rb +55 -0
  3. data/lib/morpheus/api/api_client.rb +48 -3
  4. data/lib/morpheus/api/apps_interface.rb +13 -13
  5. data/lib/morpheus/api/{zones_interface.rb → clouds_interface.rb} +10 -10
  6. data/lib/morpheus/api/deploy_interface.rb +4 -4
  7. data/lib/morpheus/api/groups_interface.rb +3 -3
  8. data/lib/morpheus/api/instance_types_interface.rb +2 -2
  9. data/lib/morpheus/api/instances_interface.rb +35 -19
  10. data/lib/morpheus/api/key_pairs_interface.rb +60 -0
  11. data/lib/morpheus/api/license_interface.rb +29 -0
  12. data/lib/morpheus/api/load_balancers_interface.rb +72 -0
  13. data/lib/morpheus/api/logs_interface.rb +37 -0
  14. data/lib/morpheus/api/options_interface.rb +20 -0
  15. data/lib/morpheus/api/provision_types_interface.rb +27 -0
  16. data/lib/morpheus/api/roles_interface.rb +73 -0
  17. data/lib/morpheus/api/security_group_rules_interface.rb +3 -3
  18. data/lib/morpheus/api/security_groups_interface.rb +5 -5
  19. data/lib/morpheus/api/servers_interface.rb +67 -3
  20. data/lib/morpheus/api/task_sets_interface.rb +46 -0
  21. data/lib/morpheus/api/tasks_interface.rb +72 -0
  22. data/lib/morpheus/api/users_interface.rb +72 -0
  23. data/lib/morpheus/cli.rb +27 -4
  24. data/lib/morpheus/cli/accounts.rb +306 -0
  25. data/lib/morpheus/cli/apps.rb +58 -1
  26. data/lib/morpheus/cli/cli_command.rb +87 -0
  27. data/lib/morpheus/cli/cli_registry.rb +6 -1
  28. data/lib/morpheus/cli/{zones.rb → clouds.rb} +99 -70
  29. data/lib/morpheus/cli/credentials.rb +23 -11
  30. data/lib/morpheus/cli/error_handler.rb +31 -11
  31. data/lib/morpheus/cli/groups.rb +1 -0
  32. data/lib/morpheus/cli/hosts.rb +567 -0
  33. data/lib/morpheus/cli/instances.rb +588 -292
  34. data/lib/morpheus/cli/key_pairs.rb +393 -0
  35. data/lib/morpheus/cli/license.rb +118 -0
  36. data/lib/morpheus/cli/load_balancers.rb +366 -0
  37. data/lib/morpheus/cli/mixins/accounts_helper.rb +193 -0
  38. data/lib/morpheus/cli/option_types.rb +260 -0
  39. data/lib/morpheus/cli/roles.rb +164 -0
  40. data/lib/morpheus/cli/security_group_rules.rb +4 -9
  41. data/lib/morpheus/cli/shell.rb +108 -0
  42. data/lib/morpheus/cli/tasks.rb +370 -0
  43. data/lib/morpheus/cli/users.rb +325 -0
  44. data/lib/morpheus/cli/version.rb +1 -1
  45. data/lib/morpheus/cli/workflows.rb +100 -0
  46. data/lib/morpheus/formatters.rb +43 -0
  47. data/morpheus-cli.gemspec +1 -1
  48. metadata +33 -10
  49. 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
- creds = load_saved_credentials
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
- puts "No Credentials on File for this Appliance: "
18
- puts "Enter Username: "
19
- username = $stdin.gets.chomp!
20
- puts "Enter Password: "
21
- password = STDIN.noecho(&:gets).chomp!
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
- save_credentials(access_token)
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 !response['success']
12
- print red,bold, "\n"
13
- if response['msg']
14
- puts response['msg']
15
- end
16
- if response['errors']
17
- response['errors'].each do |key, value|
18
- print "* #{key}: #{value}\n"
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
- end
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
@@ -3,6 +3,7 @@ require 'io/console'
3
3
  require 'rest_client'
4
4
  require 'term/ansicolor'
5
5
  require 'optparse'
6
+ require 'table_print'
6
7
  require 'morpheus/cli/cli_command'
7
8
 
8
9
  class Morpheus::Cli::Groups
@@ -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