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.
@@ -10,7 +10,7 @@ class Morpheus::Cli::BackupJobsCommand
10
10
 
11
11
  set_command_name :'backup-jobs'
12
12
 
13
- register_subcommands :list, :get, :add, :update, :remove, :run
13
+ register_subcommands :list, :get, :add, :update, :remove, :execute
14
14
 
15
15
  def connect(opts)
16
16
  @api_client = establish_remote_appliance_connection(opts)
@@ -27,7 +27,7 @@ class Morpheus::Cli::BackupJobsCommand
27
27
  params = {}
28
28
  ref_ids = []
29
29
  optparse = Morpheus::Cli::OptionParser.new do |opts|
30
- opts.banner = subcommand_usage("[search]")
30
+ opts.banner = "Usage: #{prog_name} backups list-jobs [search]"
31
31
  build_standard_list_options(opts, options)
32
32
  opts.footer = "List backup jobs."
33
33
  end
@@ -50,7 +50,7 @@ class Morpheus::Cli::BackupJobsCommand
50
50
  if backup_jobs.empty?
51
51
  print yellow,"No backup jobs found.",reset,"\n"
52
52
  else
53
- print as_pretty_table(backup_jobs, backup_job_column_definitions.upcase_keys!, options)
53
+ print as_pretty_table(backup_jobs, backup_job_list_column_definitions.upcase_keys!, options)
54
54
  print_results_pagination(json_response)
55
55
  end
56
56
  print reset,"\n"
@@ -62,7 +62,8 @@ class Morpheus::Cli::BackupJobsCommand
62
62
  params = {}
63
63
  options = {}
64
64
  optparse = Morpheus::Cli::OptionParser.new do |opts|
65
- opts.banner = subcommand_usage("[job]")
65
+ # opts.banner = subcommand_usage("[job]")
66
+ opts.banner = "Usage: #{prog_name} backups get-job [job]"
66
67
  build_standard_get_options(opts, options)
67
68
  opts.footer = <<-EOT
68
69
  Get details about a specific backup job.
@@ -99,9 +100,21 @@ EOT
99
100
  json_response = @backup_jobs_interface.get(id, params)
100
101
  backup_job = json_response['job']
101
102
  render_response(json_response, options, 'job') do
103
+ backup_job = json_response['job']
104
+ backups = backup_job['backups'] || []
102
105
  print_h1 "Backup Job Details", [], options
103
106
  print cyan
104
- print_description_list(backup_job_column_definitions, backup_job)
107
+ columns = backup_job_column_definitions
108
+ columns.delete("Provider") if backup_job['backupProvider'].nil?
109
+ columns.delete("Repository") if backup_job['backupRepository'].nil?
110
+ print_description_list(columns, backup_job)
111
+ # print reset,"\n"
112
+ print_h2 "Backups", options
113
+ if backups.empty?
114
+ print yellow,"This job has no backups associated with it.",reset,"\n"
115
+ else
116
+ print as_pretty_table(backups, [:id, :name], options)
117
+ end
105
118
  print reset,"\n"
106
119
  end
107
120
  return 0, nil
@@ -111,7 +124,7 @@ EOT
111
124
  options = {}
112
125
  params = {}
113
126
  optparse = Morpheus::Cli::OptionParser.new do |opts|
114
- opts.banner = subcommand_usage("[name] [options]")
127
+ opts.banner = "Usage: #{prog_name} backups add-job [name]"
115
128
  build_option_type_options(opts, options, add_backup_job_option_types)
116
129
  build_option_type_options(opts, options, add_backup_job_advanced_option_types)
117
130
  build_standard_add_options(opts, options)
@@ -131,6 +144,9 @@ EOT
131
144
  payload.deep_merge!({'job' => parse_passed_options(options)})
132
145
  v_prompt = Morpheus::Cli::OptionTypes.prompt(add_backup_job_option_types(), options[:options], @api_client, options[:params])
133
146
  params.deep_merge!(v_prompt)
147
+ if params['scheduleId'] == 'manual' || params['scheduleId'] == ''
148
+ params['scheduleId'] = nil
149
+ end
134
150
  advanced_config = Morpheus::Cli::OptionTypes.no_prompt(add_backup_job_advanced_option_types, options[:options], @api_client, options[:params])
135
151
  advanced_config.deep_compact!
136
152
  params.deep_merge!(advanced_config)
@@ -155,7 +171,7 @@ EOT
155
171
  params = {}
156
172
  payload = {}
157
173
  optparse = Morpheus::Cli::OptionParser.new do |opts|
158
- opts.banner = subcommand_usage("[job] [options]")
174
+ opts.banner = "Usage: #{prog_name} backups update-job [job]"
159
175
  build_option_type_options(opts, options, update_backup_job_option_types)
160
176
  build_option_type_options(opts, options, update_backup_job_advanced_option_types)
161
177
  build_standard_update_options(opts, options)
@@ -177,6 +193,9 @@ EOT
177
193
  payload.deep_merge!({'job' => parse_passed_options(options)})
178
194
  v_prompt = Morpheus::Cli::OptionTypes.no_prompt(update_backup_job_option_types, options[:options], @api_client, options[:params])
179
195
  v_prompt.deep_compact!
196
+ if v_prompt['scheduleId'] == 'manual' || v_prompt['scheduleId'] == ''
197
+ v_prompt['scheduleId'] = nil
198
+ end
180
199
  params.deep_merge!(v_prompt)
181
200
  advanced_config = Morpheus::Cli::OptionTypes.no_prompt(update_backup_job_advanced_option_types, options[:options], @api_client, options[:params])
182
201
  advanced_config.deep_compact!
@@ -204,7 +223,7 @@ EOT
204
223
  options = {}
205
224
  params = {}
206
225
  optparse = Morpheus::Cli::OptionParser.new do |opts|
207
- opts.banner = subcommand_usage("[job] [options]")
226
+ opts.banner = "Usage: #{prog_name} backups remove-job [job]"
208
227
  build_standard_remove_options(opts, options)
209
228
  opts.footer = <<-EOT
210
229
  Delete a backup job.
@@ -216,28 +235,63 @@ EOT
216
235
  connect(options)
217
236
  backup_job = find_backup_job_by_name_or_id(args[0])
218
237
  return 1 if backup_job.nil?
219
- @backup_jobs_interface.setopts(options)
220
- if options[:dry_run]
221
- print_dry_run @backup_jobs_interface.dry.destroy(backup_job['id'], params)
222
- return
238
+ parse_options(options, params)
239
+ confirm!("Are you sure you want to delete the backup job #{backup_job['name']}?", options)
240
+ execute_api(@backup_jobs_interface, :destroy, [backup_job['id']], options) do |json_response|
241
+ print_green_success "Removed backup job #{backup_job['name']}"
223
242
  end
224
- unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the backup #{backup['name']}?")
225
- return 9, "aborted command"
243
+ end
244
+
245
+ def execute(args)
246
+ options = {}
247
+ params = {}
248
+ payload = {}
249
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
250
+ opts.banner = "Usage: #{prog_name} backups execute-job [job]"
251
+ build_standard_post_options(opts, options)
252
+ opts.footer = <<-EOT
253
+ Execute a backup job to create a new backup result for all the backups in the job.
254
+ [job] is required. This is the name or id of a backup job.
255
+ EOT
226
256
  end
227
- json_response = @backup_jobs_interface.destroy(backup_job['id'], params)
228
- render_response(json_response, options) do
229
- print_green_success "Removed backup job #{backup_job['name']}"
257
+ optparse.parse!(args)
258
+ verify_args!(args:args, optparse:optparse, count:1)
259
+ connect(options)
260
+ backup_job = find_backup_job_by_name_or_id(args[0])
261
+ return 1 if backup_job.nil?
262
+ parse_payload(options)
263
+ execute_api(@backup_jobs_interface, :execute_job, [backup_job['id']], options, 'job') do |json_response|
264
+ print_green_success "Executing backup job #{backup_job['name']}"
265
+ # should get the result maybe, or could even support refreshing until it is complete...
266
+ # return _get(backup_job["id"], {}, options)
230
267
  end
231
- return 0, nil
232
268
  end
233
269
 
234
270
  private
235
271
 
236
272
  def backup_job_column_definitions()
273
+ {
274
+ "ID" => 'id',
275
+ "Name" => 'name',
276
+ "Code" => 'code',
277
+ "Schedule" => lambda {|it| it['schedule']['name'] rescue '' },
278
+ "Next" => lambda {|it| format_local_dt(it['nextFire']) },
279
+ "Retention Count" => lambda {|it| it['retentionCount'] rescue '' },
280
+ "Provider" => lambda {|it| it['backupProvider']['name'] rescue '' },
281
+ "Repository" => lambda {|it| it['backupRepository']['name'] rescue '' },
282
+ "Source" => lambda {|it| it['source'] },
283
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
284
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
285
+ }
286
+ end
287
+
288
+ def backup_job_list_column_definitions()
237
289
  {
238
290
  "ID" => 'id',
239
291
  "Name" => 'name',
240
292
  "Schedule" => lambda {|it| it['schedule']['name'] rescue '' },
293
+ "Next" => lambda {|it| format_local_dt(it['nextFire']) },
294
+ "Retention Count" => lambda {|it| it['retentionCount'] rescue '' },
241
295
  "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
242
296
  "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
243
297
  }
@@ -246,9 +300,12 @@ EOT
246
300
  def add_backup_job_option_types
247
301
  [
248
302
  {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
249
- #{'fieldName' => 'code', 'fieldLabel' => 'Code', 'type' => 'text', 'required' => false, 'displayOrder' => 2},
303
+ {'fieldName' => 'code', 'fieldLabel' => 'Code', 'type' => 'text', 'required' => false, 'displayOrder' => 2},
250
304
  {'fieldName' => 'retentionCount', 'fieldLabel' => 'Retention Count', 'type' => 'number', 'displayOrder' => 3},
251
- {'fieldName' => 'scheduleId', 'fieldLabel' => 'Schedule', 'type' => 'select', 'optionSource' => 'executeSchedules', 'displayOrder' => 4}, # should use jobSchedules instead maybe? do we support manual schedules for backups?
305
+ {'fieldName' => 'scheduleId', 'fieldLabel' => 'Schedule', 'type' => 'select', 'optionSource' => lambda { |api_client, api_params|
306
+ schedules = api_client.options.options_for_source('executeSchedules',{})['data']
307
+ [{"name" => "Manual", "value" => "manual"}] + schedules
308
+ }, 'displayOrder' => 4},
252
309
  ]
253
310
  end
254
311
 
@@ -0,0 +1,144 @@
1
+ require 'morpheus/cli/cli_command'
2
+
3
+ class Morpheus::Cli::BackupRestoresCommand
4
+ include Morpheus::Cli::CliCommand
5
+ include Morpheus::Cli::BackupsHelper
6
+ # include Morpheus::Cli::ProvisioningHelper
7
+ # include Morpheus::Cli::OptionSourceHelper
8
+
9
+ set_command_hidden # hide until ready
10
+
11
+ set_command_name :'backup-restores'
12
+
13
+ register_subcommands :list, :get, :remove
14
+
15
+ def connect(opts)
16
+ @api_client = establish_remote_appliance_connection(opts)
17
+ @backups_interface = @api_client.backups
18
+ @backup_restores_interface = @api_client.backup_restores
19
+ end
20
+
21
+ def handle(args)
22
+ handle_subcommand(args)
23
+ end
24
+
25
+ def list(args)
26
+ options = {}
27
+ params = {}
28
+ ref_ids = []
29
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
30
+ opts.banner = "Usage: #{prog_name} backups list-restores [search]"
31
+ build_standard_list_options(opts, options)
32
+ opts.footer = "List backup restores."
33
+ end
34
+ optparse.parse!(args)
35
+ connect(options)
36
+ # verify_args!(args:args, optparse:optparse, count:0)
37
+ if args.count > 0
38
+ options[:phrase] = args.join(" ")
39
+ end
40
+ params.merge!(parse_list_options(options))
41
+ @backup_restores_interface.setopts(options)
42
+ if options[:dry_run]
43
+ print_dry_run @backup_restores_interface.dry.list(params)
44
+ return
45
+ end
46
+ json_response = @backup_restores_interface.list(params)
47
+ backup_restores = json_response['restores']
48
+ render_response(json_response, options, 'restores') do
49
+ print_h1 "Morpheus Backup Restores", parse_list_subtitles(options), options
50
+ if backup_restores.empty?
51
+ print yellow,"No backup restores found.",reset,"\n"
52
+ else
53
+ print as_pretty_table(backup_restores, backup_restore_list_column_definitions.upcase_keys!, options)
54
+ print_results_pagination(json_response)
55
+ end
56
+ print reset,"\n"
57
+ end
58
+ return 0, nil
59
+ end
60
+
61
+ def get(args)
62
+ params = {}
63
+ options = {}
64
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
65
+ opts.banner = "Usage: #{prog_name} backups get-restore [restore]"
66
+ build_standard_get_options(opts, options)
67
+ opts.footer = <<-EOT
68
+ Get details about a specific backup restore.
69
+ [restore] is required. This is the id of a backup restore.
70
+ EOT
71
+ end
72
+ optparse.parse!(args)
73
+ verify_args!(args:args, optparse:optparse, min:1)
74
+ connect(options)
75
+ id_list = parse_id_list(args)
76
+ id_list = id_list.collect do |id|
77
+ if id.to_s =~ /\A\d{1,}\Z/
78
+ id
79
+ else
80
+ backup_restore = find_backup_restore_by_name(id)
81
+ if backup_restore
82
+ backup_restore['id']
83
+ else
84
+ return 1, "backup restore not found for name '#{id}'"
85
+ end
86
+ end
87
+ end
88
+ return run_command_for_each_arg(id_list) do |arg|
89
+ _get(arg, params, options)
90
+ end
91
+ end
92
+
93
+ def _get(id, params, options)
94
+ @backup_restores_interface.setopts(options)
95
+ if options[:dry_run]
96
+ print_dry_run @backup_restores_interface.dry.get(id, params)
97
+ return
98
+ end
99
+ json_response = @backup_restores_interface.get(id, params)
100
+ backup_restore = json_response['restore']
101
+ render_response(json_response, options, 'restore') do
102
+ backup_restore = json_response['restore']
103
+ backups = backup_restore['backups'] || []
104
+ print_h1 "Backup Restore Details", [], options
105
+ print cyan
106
+ print_description_list(backup_restore_column_definitions, backup_restore)
107
+ if backup_restore['errorMessage']
108
+ print_h2 "Error Message", options
109
+ print red, backup_restore['errorMessage'], reset, "\n"
110
+ end
111
+ print reset,"\n"
112
+ end
113
+ return 0, nil
114
+ end
115
+
116
+ def remove(args)
117
+ options = {}
118
+ params = {}
119
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
120
+ opts.banner = "Usage: #{prog_name} backups remove-restore [restore]"
121
+ build_standard_remove_options(opts, options)
122
+ opts.footer = <<-EOT
123
+ Delete a backup restore.
124
+ [restore] is required. This is the id of a backup restore.
125
+ EOT
126
+ end
127
+ optparse.parse!(args)
128
+ verify_args!(args:args, optparse:optparse, count:1)
129
+ connect(options)
130
+ backup_restore = @backup_restores_interface.get(args[0])['restore']
131
+ #backup_restore = find_backup_restore_by_name_or_id(args[0])
132
+ #return 1 if backup_restore.nil?
133
+ parse_options(options, params)
134
+ confirm!("Are you sure you want to delete the backup restore #{backup_restore['id']}?", options)
135
+ execute_api(@backup_restores_interface, :destroy, [backup_restore['id']], options) do |json_response|
136
+ print_green_success "Removed backup restore #{backup_restore['name']}"
137
+ end
138
+ end
139
+
140
+ private
141
+
142
+ # helper methods are defined in BackupsHelper
143
+
144
+ end
@@ -0,0 +1,149 @@
1
+ require 'morpheus/cli/cli_command'
2
+
3
+ class Morpheus::Cli::BackupResultsCommand
4
+ include Morpheus::Cli::CliCommand
5
+ include Morpheus::Cli::BackupsHelper
6
+ # include Morpheus::Cli::ProvisioningHelper
7
+ # include Morpheus::Cli::OptionSourceHelper
8
+
9
+ set_command_hidden # hide and prefer backups list-results, get-result, etc. for now
10
+
11
+ set_command_name :'backup-results'
12
+
13
+ register_subcommands :list, :get, :remove
14
+
15
+ def connect(opts)
16
+ @api_client = establish_remote_appliance_connection(opts)
17
+ @backups_interface = @api_client.backups
18
+ @backup_results_interface = @api_client.backup_results
19
+ end
20
+
21
+ def handle(args)
22
+ handle_subcommand(args)
23
+ end
24
+
25
+ def list(args)
26
+ options = {}
27
+ params = {}
28
+ ref_ids = []
29
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
30
+ opts.banner = "Usage: #{prog_name} backups list-results [search]"
31
+ opts.on('--backup BACKUP', String, "Backup Name or ID") do |val|
32
+ options[:backup] = val
33
+ end
34
+ opts.on('--instance INSTANCE', String, "Instance Name or ID") do |val|
35
+ options[:instance] = val
36
+ end
37
+ build_standard_list_options(opts, options)
38
+ opts.footer = "List backup results."
39
+ end
40
+ optparse.parse!(args)
41
+ connect(options)
42
+ # verify_args!(args:args, optparse:optparse, max:1)
43
+ parse_list_options!(args, options, params)
44
+ execute_api(@backup_results_interface, :list, [], options, 'results') do |json_response|
45
+ backup_results = json_response['results']
46
+ subtitles = []
47
+ subtitles << "Backup: #{options[:backup]}" if options[:backup]
48
+ subtitles += parse_list_subtitles(options)
49
+ print_h1 "Morpheus Backup Results", subtitles, options
50
+ if backup_results.empty?
51
+ print yellow,"No backup results found.",reset,"\n"
52
+ else
53
+ print as_pretty_table(backup_results, backup_result_list_column_definitions.upcase_keys!, options)
54
+ print_results_pagination(json_response)
55
+ end
56
+ print reset,"\n"
57
+ end
58
+ end
59
+
60
+ def get(args)
61
+ params = {}
62
+ options = {}
63
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
64
+ opts.banner = "Usage: #{prog_name} backups get-result [result]"
65
+ build_standard_get_options(opts, options)
66
+ opts.footer = <<-EOT
67
+ Get details about a specific backup result.
68
+ [result] is required. This is the id of a backup result.
69
+ EOT
70
+ end
71
+ optparse.parse!(args)
72
+ verify_args!(args:args, optparse:optparse, min:1)
73
+ connect(options)
74
+ id_list = parse_id_list(args)
75
+ id_list = id_list.collect do |id|
76
+ if id.to_s =~ /\A\d{1,}\Z/
77
+ id
78
+ else
79
+ backup_result = find_backup_result_by_name(id)
80
+ if backup_result
81
+ backup_result['id']
82
+ else
83
+ return 1, "backup result not found for name '#{id}'"
84
+ end
85
+ end
86
+ end
87
+ return run_command_for_each_arg(id_list) do |arg|
88
+ _get(arg, params, options)
89
+ end
90
+ end
91
+
92
+ def _get(id, params, options)
93
+ @backup_results_interface.setopts(options)
94
+ if options[:dry_run]
95
+ print_dry_run @backup_results_interface.dry.get(id, params)
96
+ return
97
+ end
98
+ json_response = @backup_results_interface.get(id, params)
99
+ backup_result = json_response['result']
100
+ render_response(json_response, options, 'result') do
101
+ backup_result = json_response['result']
102
+ backups = backup_result['backups'] || []
103
+ print_h1 "Backup Result Details", [], options
104
+ print cyan
105
+ print_description_list(backup_result_column_definitions, backup_result)
106
+ if backup_result['errorMessage']
107
+ print_h2 "Error Message", options
108
+ print red, backup_result['errorMessage'], reset, "\n"
109
+ end
110
+ print reset,"\n"
111
+ end
112
+ return 0, nil
113
+ end
114
+
115
+ def remove(args)
116
+ options = {}
117
+ params = {}
118
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
119
+ opts.banner = "Usage: #{prog_name} backups remove-result [result]"
120
+ build_standard_remove_options(opts, options)
121
+ opts.footer = <<-EOT
122
+ Delete a backup result.
123
+ [result] is required. This is the id of a backup result.
124
+ EOT
125
+ end
126
+ optparse.parse!(args)
127
+ verify_args!(args:args, optparse:optparse, count:1)
128
+ connect(options)
129
+ backup_result = @backup_results_interface.get(args[0])['result']
130
+ # backup_result = find_backup_result_by_name_or_id(args[0])
131
+ # return 1 if backup_result.nil?
132
+ parse_options(options, params)
133
+ confirm!("Are you sure you want to delete the backup result #{backup_result['id']}?", options)
134
+ execute_api(@backup_results_interface, :destroy, [backup_result['id']], options) do |json_response|
135
+ print_green_success "Removed backup result #{backup_result['name']}"
136
+ end
137
+ end
138
+
139
+ private
140
+
141
+ # helper methods are defined in BackupsHelper
142
+
143
+ def parse_list_options!(args, options, params)
144
+ parse_parameter_as_resource_id!(:backup, options, params, 'backupId')
145
+ parse_parameter_as_resource_id!(:instance, options, params, 'instanceId')
146
+ super
147
+ end
148
+
149
+ end