morpheus-cli 6.1.2 → 6.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/lib/morpheus/api/api_client.rb +8 -0
- data/lib/morpheus/api/backup_jobs_interface.rb +4 -0
- data/lib/morpheus/api/backup_restores_interface.rb +23 -0
- data/lib/morpheus/api/backup_results_interface.rb +28 -0
- data/lib/morpheus/api/backups_interface.rb +5 -4
- data/lib/morpheus/cli/cli_command.rb +172 -45
- data/lib/morpheus/cli/commands/appliance_settings_command.rb +7 -19
- data/lib/morpheus/cli/commands/apps.rb +1 -1
- data/lib/morpheus/cli/commands/backup_jobs_command.rb +77 -20
- data/lib/morpheus/cli/commands/backup_restores_command.rb +144 -0
- data/lib/morpheus/cli/commands/backup_results_command.rb +149 -0
- data/lib/morpheus/cli/commands/backups_command.rb +214 -93
- data/lib/morpheus/cli/commands/hosts.rb +15 -2
- data/lib/morpheus/cli/commands/instances.rb +18 -3
- data/lib/morpheus/cli/commands/service_catalog_command.rb +50 -83
- data/lib/morpheus/cli/commands/view.rb +20 -20
- data/lib/morpheus/cli/mixins/backups_helper.rb +58 -0
- data/lib/morpheus/cli/mixins/print_helper.rb +27 -4
- data/lib/morpheus/cli/option_types.rb +10 -7
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/formatters.rb +1 -1
- data/lib/morpheus/routes.rb +18 -3
- metadata +6 -2
@@ -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
|
-
|
44
|
-
|
45
|
-
|
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
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
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
|
-
|
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
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
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' =>
|
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
|
222
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
273
|
-
|
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
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
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
|
-
|
308
|
-
|
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
|
-
|
311
|
-
|
312
|
-
|
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
|
-
|
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
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
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("[
|
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
|
-
|
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
|
-
|
5331
|
+
exit 1
|
5317
5332
|
else
|
5318
5333
|
return workflows[0]
|
5319
5334
|
end
|