morpheus-cli 6.1.2 → 6.2.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.
@@ -1,3 +1,4 @@
1
+
1
2
  require 'morpheus/cli/cli_command'
2
3
 
3
4
  class Morpheus::Cli::BackupsCommand
@@ -5,17 +6,20 @@ class Morpheus::Cli::BackupsCommand
5
6
  include Morpheus::Cli::BackupsHelper
6
7
  include Morpheus::Cli::ProvisioningHelper
7
8
  include Morpheus::Cli::OptionSourceHelper
8
-
9
- set_command_hidden # hide until ready
10
9
 
10
+ set_command_description "View and manage backups"
11
11
  set_command_name :'backups'
12
+ register_subcommands :list, :get, :add, :update, :remove, :execute #, :restore
13
+ register_subcommands :list_jobs, :get_job, :add_job, :update_job, :remove_job, :execute_job
14
+ register_subcommands :list_results, :get_result, :remove_result
15
+ register_subcommands :list_restores, :get_restore, :remove_restore
12
16
 
13
- register_subcommands :list, :get, :add, :update, :remove, :run, :restore
14
-
15
17
  def connect(opts)
16
18
  @api_client = establish_remote_appliance_connection(opts)
17
19
  @backups_interface = @api_client.backups
18
20
  @backup_jobs_interface = @api_client.backup_jobs
21
+ @backup_results_interface = @api_client.backup_results
22
+ @backup_restores_interface = @api_client.backup_restores
19
23
  @instances_interface = @api_client.instances
20
24
  @servers_interface = @api_client.servers
21
25
  end
@@ -40,14 +44,9 @@ class Morpheus::Cli::BackupsCommand
40
44
  options[:phrase] = args.join(" ")
41
45
  end
42
46
  params.merge!(parse_list_options(options))
43
- @backups_interface.setopts(options)
44
- if options[:dry_run]
45
- print_dry_run @backups_interface.dry.list(params)
46
- return
47
- end
48
- json_response = @backups_interface.list(params)
49
- backups = json_response['backups']
50
- render_response(json_response, options, 'backups') do
47
+ parse_options(options, params)
48
+ execute_api(@backups_interface, :list, [], options, 'backup') do |json_response|
49
+ backups = json_response['backups']
51
50
  print_h1 "Morpheus Backups", parse_list_subtitles(options), options
52
51
  if backups.empty?
53
52
  print cyan,"No backups found.",reset,"\n"
@@ -74,6 +73,7 @@ EOT
74
73
  optparse.parse!(args)
75
74
  verify_args!(args:args, optparse:optparse, min:1)
76
75
  connect(options)
76
+ parse_options(options, params)
77
77
  id_list = parse_id_list(args)
78
78
  return run_command_for_each_arg(id_list) do |arg|
79
79
  _get(arg, params, options)
@@ -88,14 +88,10 @@ EOT
88
88
  end
89
89
  id = record['id']
90
90
  end
91
- @backups_interface.setopts(options)
92
- if options[:dry_run]
93
- print_dry_run @backups_interface.dry.get(id, params)
94
- return
95
- end
96
- json_response = @backups_interface.get(id, params)
97
- backup = json_response['backup']
98
- render_response(json_response, options, 'backup') do
91
+ options[:params] = params # parse_options(options, params)
92
+ options.delete(:payload)
93
+ execute_api(@backups_interface, :get, [id], options, 'backup') do |json_response|
94
+ backup = json_response['backup']
99
95
  print_h1 "Backup Details", [], options
100
96
  print cyan
101
97
  columns = backup_column_definitions
@@ -105,7 +101,6 @@ EOT
105
101
  print_description_list(columns, backup, options)
106
102
  print reset,"\n"
107
103
  end
108
- return 0, nil
109
104
  end
110
105
 
111
106
  def add(args)
@@ -113,7 +108,6 @@ EOT
113
108
  params = {}
114
109
  optparse = Morpheus::Cli::OptionParser.new do |opts|
115
110
  opts.banner = subcommand_usage("[name] [options]")
116
- # build_option_type_options(opts, options, add_backup_option_types)
117
111
  opts.on('--source VALUE', String, "Backup Source: instance, host or provider") do |val|
118
112
  options[:options]['source'] = val
119
113
  end
@@ -133,7 +127,8 @@ EOT
133
127
  opts.on('--name VALUE', String, "Name") do |val|
134
128
  options[:options]['name'] = val
135
129
  end
136
- build_standard_add_options(opts, options)
130
+ # build_option_type_options(opts, options, add_backup_option_types)
131
+ build_standard_add_many_options(opts, options)
137
132
  opts.footer = <<-EOT
138
133
  Create a new backup.
139
134
  EOT
@@ -142,13 +137,10 @@ EOT
142
137
  verify_args!(args:args, optparse:optparse, min:0, max:1)
143
138
  options[:options]['name'] = args[0] if args[0]
144
139
  connect(options)
145
- payload = {}
146
- if options[:payload]
147
- payload = options[:payload]
148
- payload.deep_merge!({'backup' => parse_passed_options(options)})
149
- else
150
- payload.deep_merge!({'backup' => parse_passed_options(options)})
151
-
140
+ parse_payload(options, 'backup') do |payload|
141
+ # v_prompt = Morpheus::Cli::OptionTypes.no_prompt(add_backup_option_types, options[:options], @api_client)
142
+ # v_prompt.deep_compact!.booleanize! # remove empty values and convert checkbox "on" and "off" to true and false
143
+ # params.deep_merge!(v_prompt)
152
144
  location_type = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'source', 'fieldLabel' => 'Source', 'type' => 'select', 'selectOptions' => [{'name' => 'Instance', 'value' => 'instance'}, {'name' => 'Host', 'value' => 'server'}, {'name' => 'Provider', 'value' => 'provider'}], 'defaultValue' => 'instance', 'required' => true, 'description' => 'Where is the backup located?'}], options[:options], @api_client)['source']
153
145
  params['locationType'] = location_type
154
146
  if location_type == 'instance'
@@ -183,7 +175,6 @@ EOT
183
175
  end
184
176
  elsif location_type == 'server'
185
177
 
186
-
187
178
  end
188
179
  # Backup Type
189
180
  avail_backup_types = (create_results['backupTypes'] || []).collect {|it| {'name' => it['name'], 'value' => it['code']} }
@@ -197,9 +188,15 @@ EOT
197
188
  params['jobAction'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'jobAction', 'fieldLabel' => 'Backup Job Type', 'type' => 'select', 'optionSource' => 'backupJobActions', 'required' => true, 'defaultValue' => 'new'}], options[:options], @api_client)['jobAction']
198
189
  if params['jobAction'] == 'new'
199
190
  params['jobName'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'jobName', 'fieldLabel' => 'Job Name', 'type' => 'text', 'required' => false, 'defaultValue' => nil}], options[:options], @api_client)['jobName']
200
- default_retention_count = create_results['backup'] ? create_results['backup']['retentionCount'] : nil
191
+ default_retention_count = (create_results['backup'] && create_results['backup']['retentionCount']) ? create_results['backup']['retentionCount'] : ((create_results['backupSettings'] && create_results['backupSettings']['retentionCount']) ? create_results['backupSettings']['retentionCount'] : nil)
201
192
  params['retentionCount'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'retentionCount', 'fieldLabel' => 'Retention Count', 'type' => 'number', 'required' => false, 'defaultValue' => default_retention_count}], options[:options], @api_client)['retentionCount']
202
- params['jobSchedule'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'jobSchedule', 'fieldLabel' => 'Backup Schedule', 'type' => 'select', 'optionSource' => 'executeSchedules', 'required' => true}], options[:options], @api_client)['jobSchedule']
193
+ params['jobSchedule'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'jobSchedule', 'fieldLabel' => 'Backup Schedule', 'type' => 'select', 'optionSource' => lambda { |api_client, api_params|
194
+ schedules = api_client.options.options_for_source('executeSchedules',{})['data']
195
+ [{"name" => "Manual", "value" => "manual"}] + schedules
196
+ }, 'required' => false}], options[:options], @api_client)['jobSchedule']
197
+ if params['jobSchedule'] == 'manual' || params['jobSchedule'] == ''
198
+ params.delete('jobSchedule')
199
+ end
203
200
  elsif params['jobAction'] == 'clone'
204
201
  params['jobId'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'jobId', 'fieldLabel' => 'Backup Job', 'type' => 'select', 'optionSource' => lambda { |api_client, api_params|
205
202
  @backup_jobs_interface.list({max:10000})['jobs'].collect {|backup_job|
@@ -215,21 +212,13 @@ EOT
215
212
  }, 'required' => true}], options[:options], @api_client)['jobId']
216
213
  end
217
214
  end
218
-
219
215
  payload['backup'].deep_merge!(params)
220
216
  end
221
- @backups_interface.setopts(options)
222
- if options[:dry_run]
223
- print_dry_run @backups_interface.dry.create(payload)
224
- return 0, nil
225
- end
226
- json_response = @backups_interface.create(payload)
227
- backup = json_response['backup']
228
- render_response(json_response, options, 'backup') do
217
+ execute_api(@backups_interface, :create, [], options, 'backup') do |json_response|
218
+ backup = json_response['backup']
229
219
  print_green_success "Added backup #{backup['name']}"
230
- return _get(backup["id"], {}, options)
220
+ _get(backup["id"], {}, options)
231
221
  end
232
- return 0, nil
233
222
  end
234
223
 
235
224
  def update(args)
@@ -238,8 +227,16 @@ EOT
238
227
  payload = {}
239
228
  optparse = Morpheus::Cli::OptionParser.new do |opts|
240
229
  opts.banner = subcommand_usage("[backup] [options]")
230
+ # opts.on('--name NAME', String, "Name") do |val|
231
+ # options[:options]['name'] = val
232
+ # end
233
+ # opts.on('--job JOB', String, "Name or ID of the Backup Job to associate this backup with") do |val|
234
+ # options[:options]['jobId'] = val
235
+ # end
236
+ # opts.on('--enabled [on|off]', String, "Can be used to disable") do |val|
237
+ # options[:options]['enabled'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s.empty?
238
+ # end
241
239
  build_option_type_options(opts, options, update_backup_option_types)
242
- build_option_type_options(opts, options, update_backup_advanced_option_types)
243
240
  build_standard_update_options(opts, options)
244
241
  opts.footer = <<-EOT
245
242
  Update a backup.
@@ -251,36 +248,21 @@ EOT
251
248
  connect(options)
252
249
  backup = find_backup_by_name_or_id(args[0])
253
250
  return 1 if backup.nil?
254
- payload = {}
255
- if options[:payload]
256
- payload = options[:payload]
257
- payload.deep_merge!({'backup' => parse_passed_options(options)})
258
- else
259
- payload.deep_merge!({'backup' => parse_passed_options(options)})
251
+ parse_payload(options, 'backup') do |payload|
260
252
  # do not prompt on update
261
- v_prompt = Morpheus::Cli::OptionTypes.no_prompt(update_backup_option_types, options[:options], @api_client, options[:params])
262
- v_prompt.deep_compact!
253
+ v_prompt = Morpheus::Cli::OptionTypes.no_prompt(update_backup_option_types, options[:options], @api_client)
254
+ v_prompt.deep_compact!.booleanize! # remove empty values and convert checkbox "on" and "off" to true and false
263
255
  params.deep_merge!(v_prompt)
264
- advanced_config = Morpheus::Cli::OptionTypes.no_prompt(update_backup_advanced_option_types, options[:options], @api_client, options[:params])
265
- advanced_config.deep_compact!
266
- params.deep_merge!(advanced_config)
267
256
  payload.deep_merge!({'backup' => params})
268
257
  if payload['backup'].empty? # || options[:no_prompt]
269
258
  raise_command_error "Specify at least one option to update.\n#{optparse}"
270
259
  end
271
260
  end
272
- @backups_interface.setopts(options)
273
- if options[:dry_run]
274
- print_dry_run @backups_interface.dry.update(backup['id'], payload)
275
- return
276
- end
277
- json_response = @backups_interface.update(backup['id'], payload)
278
- backup = json_response['backup']
279
- render_response(json_response, options, 'backup') do
261
+ execute_api(@backups_interface, :update, [backup['id']], options, 'backup') do |json_response|
262
+ backup = json_response['backup']
280
263
  print_green_success "Updated backup #{backup['name']}"
281
264
  return _get(backup["id"], {}, options)
282
265
  end
283
- return 0, nil
284
266
  end
285
267
 
286
268
  def remove(args)
@@ -299,23 +281,169 @@ EOT
299
281
  connect(options)
300
282
  backup = find_backup_by_name_or_id(args[0])
301
283
  return 1 if backup.nil?
302
- @backups_interface.setopts(options)
303
- if options[:dry_run]
304
- print_dry_run @backups_interface.dry.destroy(backup['id'], params)
305
- return
284
+ parse_options(options, params)
285
+ confirm!("Are you sure you want to delete the backup #{backup['name']}?", options)
286
+ execute_api(@backups_interface, :destroy, [backup['id']], options, 'backup') do |json_response|
287
+ print_green_success "Removed backup #{backup['name']}"
306
288
  end
307
- unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the backup #{backup['name']}?")
308
- return 9, "aborted command"
289
+ end
290
+
291
+ def execute(args)
292
+ options = {}
293
+ params = {}
294
+ payload = {}
295
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
296
+ opts.banner = subcommand_usage("[backup] [options]")
297
+ build_standard_post_options(opts, options)
298
+ opts.footer = <<-EOT
299
+ Execute a backup to create a new backup result.
300
+ [backup] is required. This is the name or id of a backup.
301
+ EOT
309
302
  end
310
- json_response = @backups_interface.destroy(backup['id'], params)
311
- render_response(json_response, options) do
312
- print_green_success "Removed backup #{backup['name']}"
303
+ optparse.parse!(args)
304
+ verify_args!(args:args, optparse:optparse, count:1)
305
+ connect(options)
306
+ backup = find_backup_by_name_or_id(args[0])
307
+ return 1 if backup.nil?
308
+ parse_payload(options)
309
+ execute_api(@backups_interface, :execute_backup, [backup['id']], options, 'backup') do |json_response|
310
+ print_green_success "Executing backup #{backup['name']}"
311
+ # should get the result maybe, or could even support refreshing until it is complete...
312
+ # return _get(backup["id"], {}, options)
313
+ end
314
+ end
315
+
316
+ def restore(args)
317
+ raise "Not Yet Implemented"
318
+ options = {}
319
+ params = {}
320
+ payload = {}
321
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
322
+ opts.banner = subcommand_usage("[backup] [result] [options]")
323
+ build_standard_post_options(opts, options)
324
+ opts.on('--result ID', String, "Backup Result ID that is being restored") do |val|
325
+ options[:options]['backupResultId'] = val
326
+ end
327
+ opts.on('--restore-instance existing|new', String, "Instance being targeted for the restore, existing to restore the current instance or new to create a new instance. The current instance is targeted by default.") do |val|
328
+ # restoreInstanceSelect=current|new and the flag on the restore object is called 'restoreToNew'
329
+ options[:options]['restoreInstanceSelect'] = val
330
+ end
331
+ opts.footer = <<-EOT
332
+ Restore a backup, replacing the existing target with the specified backup result.
333
+ [backup] is required. This is the name or id of a backup.
334
+ --result ID is required. This is the id of a backup result being restored.
335
+ EOT
336
+ end
337
+ optparse.parse!(args)
338
+ verify_args!(args:args, optparse:optparse, max:1)
339
+ connect(options)
340
+ backup = nil
341
+ backup_result = nil
342
+ if args[0]
343
+ backup = find_backup_by_name_or_id(args[0])
344
+ return 1 if backup.nil?
345
+ else
346
+ # Prompt for backup
347
+ if backup.nil?
348
+ # Backup
349
+ available_backups = @backups_interface.list({max:10000})['backups'].collect {|it| {'name' => it['name'], 'value' => it['id']}}
350
+ backup_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'backupId', 'fieldLabel' => 'Backup', 'type' => 'select', 'selectOptions' => available_backups, 'required' => true}], options[:options], @api_client)['backupId']
351
+ backup = find_backup_by_name_or_id(backup_id)
352
+ return 1 if backup.nil?
353
+ end
354
+ end
355
+ # Prompt for backup result
356
+ if backup_result.nil?
357
+
358
+ # Instance
359
+ available_backup_results = @backups_interface.list({backupId: backup['id'], max:10000})['results'].collect {|it| {'name' => it['name'], 'value' => it['id']}}
360
+ params['backupResultId'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'backupResultId', 'fieldLabel' => 'Backup Result', 'type' => 'select', 'selectOptions' => available_backup_results, 'required' => true}], options[:options], @api_client)['backupResultId']
361
+ # Name
362
+ params['name'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Backup Name'}], options[:options], @api_client)['name']
363
+ end
364
+
365
+ parse_payload(options, 'restore') do |payload|
366
+ # Prompt for restore configuration
367
+ # We should probably require identifying the instance by name or id too, just to be safe.
368
+ # Target Instance
369
+ if backup_result['instance']
370
+ params['restoreInstanceSelect'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Instance being targeted for the restore, existing to restore the current instance or new to create a new instance. By default the existing instance is restored.'}], options[:options], @api_client)['restoreInstanceSelect']
371
+ end
372
+ payload['backup'].deep_merge!(params)
373
+ end
374
+
375
+ print cyan,"#{bold}WARNING!#{reset}#{cyan} Restoring a backup will erase all data when restored to an existing instance.",reset,"\n"
376
+ confirm!("Are you sure you want to restore the backup result ID: #{backup_result['id']} Name: #{backup_result['backup']['name'] rescue ''} Date: (#{format_local_dt(backup_result['dateCreated'])})?", options)
377
+ execute_api(@backups_interface, :restore, [backup['id']], options, 'backup') do |json_response|
378
+ print_green_success "Restoring backup result ID: #{backup_result['id']} Name: #{backup_result['backup']['name'] rescue ''} Date: (#{format_local_dt(backup_result['dateCreated'])}"
379
+ # should get the restore maybe, or could even support refreshing until it is complete...
380
+ # restore = json_response["restore"]
381
+ # return _get_restore(restore["id"], {}, options)
313
382
  end
314
- return 0, nil
383
+ end
384
+
385
+ # Delegate jobs, results and restores
386
+ # to backup-jobs, backup-results and backup-restores
387
+ # which are hidden in the docs
388
+
389
+ ## Backup Jobs
390
+
391
+ def list_jobs(args)
392
+ Morpheus::Cli::BackupJobsCommand.new.list(args)
393
+ end
394
+
395
+ def get_job(args)
396
+ Morpheus::Cli::BackupJobsCommand.new.get(args)
397
+ end
398
+
399
+ def add_job(args)
400
+ Morpheus::Cli::BackupJobsCommand.new.add(args)
401
+ end
402
+
403
+ def update_job(args)
404
+ Morpheus::Cli::BackupJobsCommand.new.update(args)
405
+ end
406
+
407
+ def remove_job(args)
408
+ Morpheus::Cli::BackupJobsCommand.new.remove(args)
409
+ end
410
+
411
+ def execute_job(args)
412
+ Morpheus::Cli::BackupJobsCommand.new.execute(args)
413
+ end
414
+
415
+ ## Backup Results
416
+
417
+ def list_results(args)
418
+ Morpheus::Cli::BackupResultsCommand.new.list(args)
419
+ end
420
+
421
+ def get_result(args)
422
+ Morpheus::Cli::BackupResultsCommand.new.get(args)
423
+ end
424
+
425
+ def remove_result(args)
426
+ Morpheus::Cli::BackupResultsCommand.new.remove(args)
427
+ end
428
+
429
+ ## Backup Restores
430
+
431
+ def list_restores(args)
432
+ Morpheus::Cli::BackupRestoresCommand.new.list(args)
433
+ end
434
+
435
+ def get_restore(args)
436
+ Morpheus::Cli::BackupRestoresCommand.new.get(args)
437
+ end
438
+
439
+ def remove_restore(args)
440
+ Morpheus::Cli::BackupRestoresCommand.new.remove(args)
315
441
  end
316
442
 
317
443
  private
318
444
 
445
+ ## Backups
446
+
319
447
  def backup_list_column_definitions()
320
448
  {
321
449
  "ID" => 'id',
@@ -345,12 +473,13 @@ EOT
345
473
  "Host" => lambda {|it| it['server']['name'] rescue '' },
346
474
  "Schedule" => lambda {|it| it['schedule']['name'] rescue '' },
347
475
  "Backup Job" => lambda {|it| it['job']['name'] rescue '' },
476
+ "Enabled" => lambda {|it| format_boolean(it['enabled']) },
348
477
  "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
349
478
  "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
350
479
  }
351
480
  end
352
481
 
353
- # this is not so simple, need to first choose select instance, host or provider
482
+ # not used atm, this is not so simple, need to first choose select instance, host or provider
354
483
  def add_backup_option_types
355
484
  [
356
485
  {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true},
@@ -364,24 +493,16 @@ EOT
364
493
  ]
365
494
  end
366
495
 
367
- def add_backup_advanced_option_types
368
- []
369
- end
370
-
371
496
  def update_backup_option_types
372
- add_backup_option_types.collect {|it|
373
- it.delete('required')
374
- it.delete('defaultValue')
375
- it
376
- }
377
- end
378
-
379
- def update_backup_advanced_option_types
380
- add_backup_advanced_option_types.collect {|it|
381
- it.delete('required')
382
- it.delete('defaultValue')
383
- it
384
- }
497
+ [
498
+ {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text'},
499
+ {'fieldName' => 'jobId', 'fieldLabel' => 'Backup Job', 'type' => 'select', 'optionSource' => lambda { |api_client, api_params|
500
+ @backup_jobs_interface.list({max:10000})['jobs'].collect {|backup_job|
501
+ {'name' => backup_job['name'], 'value' => backup_job['id'], 'id' => backup_job['id']}
502
+ }
503
+ } },
504
+ {'fieldName' => 'enabled', 'fieldLabel' => 'Enabled', 'type' => 'checkbox'},
505
+ ]
385
506
  end
386
507
 
387
508
  end
@@ -1500,8 +1500,19 @@ class Morpheus::Cli::Hosts
1500
1500
  params = {}
1501
1501
  options = {}
1502
1502
  optparse = Morpheus::Cli::OptionParser.new do |opts|
1503
- opts.banner = subcommand_usage("[name] [workflow] [options]")
1503
+ opts.banner = subcommand_usage("[host] [workflow] [options]")
1504
+ opts.on("--phase PHASE", String, "Task Phase to run for Provisioning workflows. The default is provision.") do |val|
1505
+ options[:phase] = val
1506
+ end
1504
1507
  build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
1508
+ opts.footer = <<-EOT
1509
+ Run workflow for a host.
1510
+ [host] is required. This is the name or id of a host
1511
+ [workflow] is required. This is the name or id of a workflow
1512
+ By default the provision phase is executed.
1513
+ Use the --phase option to execute a different phase.
1514
+ The available phases are start, stop, preProvision, provision, postProvision, preDeploy, deploy, reconfigure, teardown, startup and shutdown.
1515
+ EOT
1505
1516
  end
1506
1517
  optparse.parse!(args)
1507
1518
  if args.count != 2
@@ -1555,7 +1566,9 @@ class Morpheus::Cli::Hosts
1555
1566
  payload['taskSet']["#{workflow['id']}"] ||= {}
1556
1567
  payload['taskSet']["#{workflow['id']}"].deep_merge!(params)
1557
1568
  end
1558
-
1569
+ if options[:phase]
1570
+ payload['taskPhase'] = options[:phase]
1571
+ end
1559
1572
  begin
1560
1573
  @servers_interface.setopts(options)
1561
1574
  if options[:dry_run]
@@ -258,7 +258,7 @@ class Morpheus::Cli::Instances
258
258
  end
259
259
  row = {
260
260
  id: instance['id'],
261
- name: instance['name'],
261
+ name: instance['displayName'] ? instance['displayName'] : instance['name'],
262
262
  labels: format_list(instance['labels'], '', 3),
263
263
  connection: format_instance_connection_string(instance),
264
264
  environment: instance['instanceContext'],
@@ -3357,7 +3357,18 @@ EOT
3357
3357
  options = {}
3358
3358
  optparse = Morpheus::Cli::OptionParser.new do |opts|
3359
3359
  opts.banner = subcommand_usage("[instance] [workflow] [options]")
3360
+ opts.on("--phase PHASE", String, "Task Phase to run for Provisioning workflows. The default is provision.") do |val|
3361
+ options[:phase] = val
3362
+ end
3360
3363
  build_common_options(opts, options, [:options, :json, :dry_run, :remote])
3364
+ opts.footer = <<-EOT
3365
+ Run workflow for an instance.
3366
+ [instance] is required. This is the name or id of an instance
3367
+ [workflow] is required. This is the name or id of a workflow
3368
+ By default the provision phase is executed.
3369
+ Use the --phase option to execute a different phase.
3370
+ The available phases are start, stop, preProvision, provision, postProvision, preDeploy, deploy, reconfigure, teardown, startup and shutdown.
3371
+ EOT
3361
3372
  end
3362
3373
  optparse.parse!(args)
3363
3374
  if args.count != 2
@@ -3391,6 +3402,9 @@ EOT
3391
3402
  # end
3392
3403
 
3393
3404
  workflow_payload = {taskSet: {"#{workflow['id']}" => params }}
3405
+ if options[:phase]
3406
+ workflow_payload['taskPhase'] = options[:phase]
3407
+ end
3394
3408
  begin
3395
3409
  @instances_interface.setopts(options)
3396
3410
  if options[:dry_run]
@@ -5298,6 +5312,7 @@ private
5298
5312
  rescue RestClient::Exception => e
5299
5313
  if e.response && e.response.code == 404
5300
5314
  print_red_alert "Workflow not found by id #{id}"
5315
+ exit 1
5301
5316
  else
5302
5317
  raise e
5303
5318
  end
@@ -5308,12 +5323,12 @@ private
5308
5323
  workflows = @task_sets_interface.list({name: name.to_s})['taskSets']
5309
5324
  if workflows.empty?
5310
5325
  print_red_alert "Workflow not found by name #{name}"
5311
- return nil
5326
+ exit 1
5312
5327
  elsif workflows.size > 1
5313
5328
  print_red_alert "#{workflows.size} workflows by name #{name}"
5314
5329
  print_workflows_table(workflows, {color: red})
5315
5330
  print reset,"\n\n"
5316
- return nil
5331
+ exit 1
5317
5332
  else
5318
5333
  return workflows[0]
5319
5334
  end