morpheus-cli 4.2.16 → 4.2.17

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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/README.md +8 -6
  4. data/lib/morpheus/api/api_client.rb +32 -14
  5. data/lib/morpheus/api/auth_interface.rb +4 -2
  6. data/lib/morpheus/api/backup_jobs_interface.rb +9 -0
  7. data/lib/morpheus/api/backups_interface.rb +16 -0
  8. data/lib/morpheus/api/deploy_interface.rb +25 -56
  9. data/lib/morpheus/api/deployments_interface.rb +43 -54
  10. data/lib/morpheus/api/doc_interface.rb +57 -0
  11. data/lib/morpheus/api/instances_interface.rb +5 -0
  12. data/lib/morpheus/api/rest_interface.rb +40 -0
  13. data/lib/morpheus/api/user_sources_interface.rb +0 -15
  14. data/lib/morpheus/api/users_interface.rb +2 -3
  15. data/lib/morpheus/benchmarking.rb +2 -2
  16. data/lib/morpheus/cli.rb +3 -1
  17. data/lib/morpheus/cli/access_token_command.rb +27 -10
  18. data/lib/morpheus/cli/apps.rb +21 -15
  19. data/lib/morpheus/cli/backup_jobs_command.rb +276 -0
  20. data/lib/morpheus/cli/backups_command.rb +271 -0
  21. data/lib/morpheus/cli/boot_scripts_command.rb +1 -1
  22. data/lib/morpheus/cli/cli_command.rb +92 -41
  23. data/lib/morpheus/cli/clusters.rb +0 -18
  24. data/lib/morpheus/cli/commands/standard/benchmark_command.rb +7 -7
  25. data/lib/morpheus/cli/commands/standard/man_command.rb +1 -1
  26. data/lib/morpheus/cli/credentials.rb +13 -9
  27. data/lib/morpheus/cli/deploy.rb +374 -0
  28. data/lib/morpheus/cli/deployments.rb +521 -197
  29. data/lib/morpheus/cli/deploys.rb +271 -126
  30. data/lib/morpheus/cli/doc.rb +182 -0
  31. data/lib/morpheus/cli/error_handler.rb +23 -8
  32. data/lib/morpheus/cli/errors.rb +3 -2
  33. data/lib/morpheus/cli/image_builder_command.rb +2 -2
  34. data/lib/morpheus/cli/instances.rb +136 -17
  35. data/lib/morpheus/cli/invoices_command.rb +51 -38
  36. data/lib/morpheus/cli/library_layouts_command.rb +1 -1
  37. data/lib/morpheus/cli/login.rb +9 -3
  38. data/lib/morpheus/cli/mixins/accounts_helper.rb +158 -100
  39. data/lib/morpheus/cli/mixins/backups_helper.rb +115 -0
  40. data/lib/morpheus/cli/mixins/deployments_helper.rb +135 -0
  41. data/lib/morpheus/cli/mixins/option_source_helper.rb +1 -1
  42. data/lib/morpheus/cli/mixins/print_helper.rb +110 -74
  43. data/lib/morpheus/cli/mixins/provisioning_helper.rb +2 -2
  44. data/lib/morpheus/cli/mixins/whoami_helper.rb +19 -6
  45. data/lib/morpheus/cli/network_routers_command.rb +1 -1
  46. data/lib/morpheus/cli/option_parser.rb +48 -5
  47. data/lib/morpheus/cli/option_types.rb +1 -1
  48. data/lib/morpheus/cli/remote.rb +3 -2
  49. data/lib/morpheus/cli/roles.rb +49 -92
  50. data/lib/morpheus/cli/security_groups.rb +7 -1
  51. data/lib/morpheus/cli/service_plans_command.rb +10 -10
  52. data/lib/morpheus/cli/setup.rb +1 -1
  53. data/lib/morpheus/cli/shell.rb +7 -6
  54. data/lib/morpheus/cli/subnets_command.rb +1 -1
  55. data/lib/morpheus/cli/tenants_command.rb +133 -163
  56. data/lib/morpheus/cli/user_groups_command.rb +20 -65
  57. data/lib/morpheus/cli/user_settings_command.rb +115 -13
  58. data/lib/morpheus/cli/user_sources_command.rb +57 -24
  59. data/lib/morpheus/cli/users.rb +210 -186
  60. data/lib/morpheus/cli/version.rb +1 -1
  61. data/lib/morpheus/cli/whitelabel_settings_command.rb +29 -5
  62. data/lib/morpheus/cli/whoami.rb +113 -6
  63. data/lib/morpheus/cli/workflows.rb +1 -1
  64. data/lib/morpheus/ext/hash.rb +21 -0
  65. data/lib/morpheus/terminal.rb +1 -0
  66. metadata +12 -3
  67. data/lib/morpheus/cli/auth_command.rb +0 -105
@@ -302,4 +302,9 @@ class Morpheus::InstancesInterface < Morpheus::APIClient
302
302
  execute(opts)
303
303
  end
304
304
 
305
+ def deploys(id, params)
306
+ # todo: make this plural??
307
+ execute(method: :get, url: "/api/instances/#{id}/deploy", params: params)
308
+ end
309
+
305
310
  end
@@ -0,0 +1,40 @@
1
+ require 'morpheus/api/api_client'
2
+
3
+ class Morpheus::RestInterface < Morpheus::APIClient
4
+
5
+ # subclasses should override in your interface
6
+ # Example: "/api/things"
7
+ def base_path
8
+ raise "#{self.class} has not defined base_path!"
9
+ end
10
+
11
+ def list(params={})
12
+ execute(method: :get, url: "#{base_path}", params: params)
13
+ end
14
+
15
+ def get(id, params={})
16
+ validate_id!(id)
17
+ execute(method: :get, url: "#{base_path}/#{id}", params: params)
18
+ end
19
+
20
+ def create(payload, params={})
21
+ execute(method: :post, url: "#{base_path}", params: params, payload: payload.to_json)
22
+ end
23
+
24
+ def update(id, payload, params={})
25
+ validate_id!(id)
26
+ execute(method: :put, url: "#{base_path}/#{id}", params: params, payload: payload.to_json)
27
+ end
28
+
29
+ def destroy(id, params = {})
30
+ validate_id!(id)
31
+ execute(method: :delete, url: "#{base_path}/#{id}", params: params)
32
+ end
33
+
34
+ protected
35
+
36
+ def validate_id!(id)
37
+ raise "#{self.class} passed a blank id!" if id.to_s.strip.empty?
38
+ end
39
+
40
+ end
@@ -24,21 +24,6 @@ class Morpheus::UserSourcesInterface < Morpheus::APIClient
24
24
  execute(opts)
25
25
  end
26
26
 
27
- # def feature_permissions(account_id, id)
28
- # url = build_url(account_id, id) + "/feature-permissions"
29
- # headers = { params: {}, authorization: "Bearer #{@access_token}" }
30
- # opts = {method: :get, url: url, timeout: 10, headers: headers}
31
- # execute(opts)
32
- # end
33
-
34
- # def available_roles(account_id, id=nil, options={})
35
- # url = build_url(account_id, id) + "/available-roles"
36
- # headers = { params: {}, authorization: "Bearer #{@access_token}" }
37
- # headers[:params].merge!(options)
38
- # opts = {method: :get, url: url, timeout: 10, headers: headers}
39
- # execute(opts)
40
- # end
41
-
42
27
  def create(account_id, options)
43
28
  url = build_url(account_id)
44
29
  headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
@@ -16,10 +16,9 @@ class Morpheus::UsersInterface < Morpheus::APIClient
16
16
  execute(opts)
17
17
  end
18
18
 
19
- def list(account_id, options={})
19
+ def list(account_id, params={})
20
20
  url = build_url(account_id)
21
- headers = { params: {}, authorization: "Bearer #{@access_token}" }
22
- headers[:params].merge!(options)
21
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
23
22
  opts = {method: :get, url: url, timeout: 10, headers: headers}
24
23
  execute(opts)
25
24
  end
@@ -218,9 +218,9 @@ module Morpheus::Benchmarking
218
218
  end
219
219
  duration_str = duration
220
220
  if @start_time && @end_time
221
- time_str = "#{seconds} seconds"
221
+ time_str = "#{seconds} s"
222
222
  elsif @start_time
223
- time_str = "#{seconds} seconds (running)"
223
+ time_str = "#{seconds} s (running)"
224
224
  else
225
225
  time_str = "(unstarted)"
226
226
  end
@@ -70,6 +70,7 @@ module Morpheus
70
70
 
71
71
  # all the known commands
72
72
  load 'morpheus/cli/remote.rb'
73
+ load 'morpheus/cli/doc.rb'
73
74
  load 'morpheus/cli/ping.rb'
74
75
  load 'morpheus/cli/setup.rb'
75
76
  load 'morpheus/cli/login.rb'
@@ -77,7 +78,6 @@ module Morpheus
77
78
  load 'morpheus/cli/whoami.rb'
78
79
  load 'morpheus/cli/access_token_command.rb'
79
80
  load 'morpheus/cli/user_settings_command.rb'
80
- # load 'morpheus/cli/auth_command.rb'
81
81
  load 'morpheus/cli/dashboard_command.rb'
82
82
  load 'morpheus/cli/recent_activity_command.rb' # deprecated, removing soon
83
83
  load 'morpheus/cli/activity_command.rb'
@@ -171,6 +171,8 @@ module Morpheus
171
171
  load 'morpheus/cli/invoices_command.rb'
172
172
  load 'morpheus/cli/guidance_command.rb'
173
173
  load 'morpheus/cli/projects_command.rb'
174
+ load 'morpheus/cli/backups_command.rb'
175
+ load 'morpheus/cli/backup_jobs_command.rb'
174
176
  # add new commands here...
175
177
 
176
178
  end
@@ -55,7 +55,7 @@ class Morpheus::Cli::AccessTokenCommand
55
55
  opts.banner = subcommand_usage()
56
56
  build_common_options(opts, options, [:remote, :quiet])
57
57
  opts.footer = "Print your current authentication credentials.\n" +
58
- "This contains tokens that should be kept secret, be careful."
58
+ "This contains tokens that should be kept secret. Be careful."
59
59
  end
60
60
  optparse.parse!(args)
61
61
  if args.count != 0
@@ -111,8 +111,18 @@ class Morpheus::Cli::AccessTokenCommand
111
111
  params = {}
112
112
  optparse = Morpheus::Cli::OptionParser.new do |opts|
113
113
  opts.banner = subcommand_usage()
114
- build_common_options(opts, options, [:auto_confirm, :remote, :dry_run, :json, :quiet])
115
- opts.footer = "Use your refresh token.\n" +
114
+ opts.on( '-T', '--token TOKEN', "Refresh Token to use. The saved credentials are used by default." ) do |val|
115
+ options[:refresh_token] = val
116
+ end
117
+ opts.on( '--token-file FILE', String, "Refresh Token File, read a file containing the refresh token." ) do |val|
118
+ token_file = File.expand_path(val)
119
+ if !File.exists?(token_file) || !File.file?(token_file)
120
+ raise ::OptionParser::InvalidOption.new("File not found: #{token_file}")
121
+ end
122
+ options[:refresh_token] = File.read(token_file).to_s.split("\n").first.strip
123
+ end
124
+ build_common_options(opts, options, [:auto_confirm, :remote, :dry_run, :json, :quiet], [:remote_username, :remote_password, :remote_token])
125
+ opts.footer = "Use the refresh token in your saved credentials, or a provided token.\n" +
116
126
  "This will replace your current access and refresh tokens with a new values.\n" +
117
127
  "Your current access token will be invalidated\n" +
118
128
  "All other users or applications with access to your token will need to update to the new token."
@@ -131,15 +141,22 @@ class Morpheus::Cli::AccessTokenCommand
131
141
  # end
132
142
  # return 1
133
143
  # end
134
- if @wallet['refresh_token'].nil?
135
- unless options[:quiet]
136
- print_error yellow,"No refresh token found for appliance #{display_appliance(@appliance_name, @appliance_url)}",reset,"\n"
137
- print_error yellow,"Use the 'login' command.",reset,"\n"
144
+ refresh_token_value = nil
145
+ if options[:refresh_token]
146
+ refresh_token_value = options[:refresh_token]
147
+ else
148
+ if @wallet['refresh_token']
149
+ refresh_token_value = @wallet['refresh_token']
150
+ else
151
+ unless options[:quiet]
152
+ print_error yellow,"No refresh token found for appliance #{display_appliance(@appliance_name, @appliance_url)}",reset,"\n"
153
+ print_error yellow,"Use the 'login' command.",reset,"\n"
154
+ end
155
+ return 1
138
156
  end
139
- return 1
140
157
  end
141
158
  if options[:dry_run]
142
- print_dry_run Morpheus::AuthInterface.new({url:@appliance_url}).setopts(options).use_refresh_token(@wallet['refresh_token'])
159
+ print_dry_run Morpheus::AuthInterface.new({url:@appliance_url}).setopts(options).use_refresh_token(refresh_token_value)
143
160
  return 0
144
161
  end
145
162
  unless options[:quiet]
@@ -160,7 +177,7 @@ class Morpheus::Cli::AccessTokenCommand
160
177
 
161
178
  # ok, let's use our refresh token
162
179
  # this regenerates the current access token.
163
- refresh_result = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).use_refresh_token(options)
180
+ refresh_result = Morpheus::Cli::Credentials.new(@appliance_name, @appliance_url).use_refresh_token(refresh_token_value, options)
164
181
  new_wallet = refresh_result
165
182
  if options[:json]
166
183
  puts as_json(refresh_result, options)
@@ -603,22 +603,28 @@ class Morpheus::Cli::Apps
603
603
  rescue TypeError, JSON::ParserError => ex
604
604
  print_error red, "Failed to parse JSON response: #{ex}", reset, "\n"
605
605
  end
606
- # The default way to print errors, except instances => []
607
- (json_response['errors'] || {}).each do |error_key, error_msg|
608
- if error_key != 'instances'
609
- print_error red, " * #{error_key} : #{error_msg}", reset, "\n"
606
+ if json_response && (json_response['errors'].nil? || json_response['errors'].empty?)
607
+ # The default way to print error msg
608
+ print_rest_exception(e, options)
609
+ else
610
+ # print errors and look for special errors.instances
611
+ # todo: just handle sub lists of errors default error handler (print_rest_exception)
612
+ (json_response['errors'] || {}).each do |error_key, error_msg|
613
+ if error_key != 'instances'
614
+ print_error red, " * #{error_key} : #{error_msg}", reset, "\n"
615
+ end
610
616
  end
611
- end
612
- # looks for special error format like instances.instanceErrors
613
- if json_response['errors'] && json_response['errors']['instances']
614
- json_response['errors']['instances'].each do |error_obj|
615
- tier_name = error_obj['tier']
616
- instance_index = error_obj['index']
617
- instance_errors = error_obj['instanceErrors']
618
- print_error red, "#{tier_name} : #{instance_index}", reset, "\n"
619
- if instance_errors
620
- instance_errors.each do |err_key, err_msg|
621
- print_error red, " * #{err_key} : #{err_msg}", reset, "\n"
617
+ # looks for special error format like instances.instanceErrors
618
+ if json_response['errors'] && json_response['errors']['instances']
619
+ json_response['errors']['instances'].each do |error_obj|
620
+ tier_name = error_obj['tier']
621
+ instance_index = error_obj['index']
622
+ instance_errors = error_obj['instanceErrors']
623
+ print_error red, "#{tier_name} : #{instance_index}", reset, "\n"
624
+ if instance_errors
625
+ instance_errors.each do |err_key, err_msg|
626
+ print_error red, " * #{err_key} : #{err_msg}", reset, "\n"
627
+ end
622
628
  end
623
629
  end
624
630
  end
@@ -0,0 +1,276 @@
1
+ require 'morpheus/cli/cli_command'
2
+
3
+ class Morpheus::Cli::BackupJobsCommand
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-jobs'
12
+
13
+ register_subcommands :list, :get, :add, :update, :remove, :run
14
+
15
+ def connect(opts)
16
+ @api_client = establish_remote_appliance_connection(opts)
17
+ @backups_interface = @api_client.backups
18
+ @backup_jobs_interface = @api_client.backup_jobs
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 = subcommand_usage("[search]")
31
+ build_standard_list_options(opts, options)
32
+ opts.footer = "List backup jobs."
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_jobs_interface.setopts(options)
42
+ if options[:dry_run]
43
+ print_dry_run @backup_jobs_interface.dry.list(params)
44
+ return
45
+ end
46
+ json_response = @backup_jobs_interface.list(params)
47
+ backup_jobs = json_response['jobs']
48
+ render_response(json_response, options, 'jobs') do
49
+ print_h1 "Morpheus Backup Jobs", parse_list_subtitles(options), options
50
+ if backup_jobs.empty?
51
+ print yellow,"No backup jobs found.",reset,"\n"
52
+ else
53
+ print as_pretty_table(backup_jobs, backup_job_column_definitions.upcase_keys!, options)
54
+ print_results_pagination(json_response)
55
+ end
56
+ print reset,"\n"
57
+ end
58
+ if backup_jobs.empty?
59
+ return 1, "no backup jobs found"
60
+ else
61
+ return 0, nil
62
+ end
63
+ end
64
+
65
+ def get(args)
66
+ params = {}
67
+ options = {}
68
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
69
+ opts.banner = subcommand_usage("[job]")
70
+ build_standard_get_options(opts, options)
71
+ opts.footer = <<-EOT
72
+ Get details about a specific backup job.
73
+ [job] is required. This is the id or name a backup job.
74
+ EOT
75
+ end
76
+ optparse.parse!(args)
77
+ verify_args!(args:args, optparse:optparse, min:1)
78
+ connect(options)
79
+ id_list = parse_id_list(args)
80
+ id_list = id_list.collect do |id|
81
+ if id.to_s =~ /\A\d{1,}\Z/
82
+ id
83
+ else
84
+ backup_job = find_backup_job_by_name(id)
85
+ if backup_job
86
+ backup_job['id']
87
+ else
88
+ return 1, "backup job not found for name '#{id}'"
89
+ end
90
+ end
91
+ end
92
+ return run_command_for_each_arg(id_list) do |arg|
93
+ _get(arg, params, options)
94
+ end
95
+ end
96
+
97
+ def _get(id, params, options)
98
+ @backup_jobs_interface.setopts(options)
99
+ if options[:dry_run]
100
+ print_dry_run @backup_jobs_interface.dry.get(id, params)
101
+ return
102
+ end
103
+ json_response = @backup_jobs_interface.get(id, params)
104
+ backup_job = json_response['job']
105
+ render_response(json_response, options, 'job') do
106
+ print_h1 "Backup Job Details", [], options
107
+ print cyan
108
+ print_description_list(backup_job_column_definitions, backup_job)
109
+ print reset,"\n"
110
+ end
111
+ return 0, nil
112
+ end
113
+
114
+ def add(args)
115
+ options = {}
116
+ params = {}
117
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
118
+ opts.banner = subcommand_usage("[name] [options]")
119
+ build_option_type_options(opts, options, add_backup_job_option_types)
120
+ build_option_type_options(opts, options, add_backup_job_advanced_option_types)
121
+ build_standard_add_options(opts, options)
122
+ opts.footer = <<-EOT
123
+ Create a new backup job
124
+ EOT
125
+ end
126
+ optparse.parse!(args)
127
+ verify_args!(args:args, optparse:optparse, min:0, max:1)
128
+ options[:options]['name'] = args[0] if args[0]
129
+ connect(options)
130
+ payload = {}
131
+ if options[:payload]
132
+ payload = options[:payload]
133
+ payload.deep_merge!({'job' => parse_passed_options(options)})
134
+ else
135
+ payload.deep_merge!({'job' => parse_passed_options(options)})
136
+ v_prompt = Morpheus::Cli::OptionTypes.prompt(add_backup_job_option_types(), options[:options], @api_client, options[:params])
137
+ params.deep_merge!(v_prompt)
138
+ advanced_config = Morpheus::Cli::OptionTypes.no_prompt(add_backup_job_advanced_option_types, options[:options], @api_client, options[:params])
139
+ advanced_config.deep_compact!
140
+ params.deep_merge!(advanced_config)
141
+ payload['job'].deep_merge!(params)
142
+ end
143
+ @backup_jobs_interface.setopts(options)
144
+ if options[:dry_run]
145
+ print_dry_run @backup_jobs_interface.dry.create(payload)
146
+ return 0, nil
147
+ end
148
+ json_response = @backup_jobs_interface.create(payload)
149
+ backup_job = json_response['job']
150
+ render_response(json_response, options, 'job') do
151
+ print_green_success "Added backup job #{backup_job['name']}"
152
+ return _get(backup_job["id"], {}, options)
153
+ end
154
+ return 0, nil
155
+ end
156
+
157
+ def update(args)
158
+ options = {}
159
+ params = {}
160
+ payload = {}
161
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
162
+ opts.banner = subcommand_usage("[job] [options]")
163
+ build_option_type_options(opts, options, update_backup_job_option_types)
164
+ build_option_type_options(opts, options, update_backup_job_advanced_option_types)
165
+ build_standard_update_options(opts, options)
166
+ opts.footer = <<-EOT
167
+ Update a backup job.
168
+ [job] is required. This is the name or id of a backup job.
169
+ EOT
170
+ end
171
+ optparse.parse!(args)
172
+ verify_args!(args:args, optparse:optparse, count:1)
173
+ connect(options)
174
+ backup_job = find_backup_job_by_name_or_id(args[0])
175
+ return 1 if backup_job.nil?
176
+ payload = {}
177
+ if options[:payload]
178
+ payload = options[:payload]
179
+ payload.deep_merge!({'job' => parse_passed_options(options)})
180
+ else
181
+ payload.deep_merge!({'job' => parse_passed_options(options)})
182
+ v_prompt = Morpheus::Cli::OptionTypes.no_prompt(update_backup_job_option_types, options[:options], @api_client, options[:params])
183
+ v_prompt.deep_compact!
184
+ params.deep_merge!(v_prompt)
185
+ advanced_config = Morpheus::Cli::OptionTypes.no_prompt(update_backup_job_advanced_option_types, options[:options], @api_client, options[:params])
186
+ advanced_config.deep_compact!
187
+ params.deep_merge!(advanced_config)
188
+ payload.deep_merge!({'job' => params})
189
+ if payload['job'].empty? # || options[:no_prompt]
190
+ raise_command_error "Specify at least one option to update.\n#{optparse}"
191
+ end
192
+ end
193
+ @backup_jobs_interface.setopts(options)
194
+ if options[:dry_run]
195
+ print_dry_run @backup_jobs_interface.dry.update(backup_job['id'], payload)
196
+ return
197
+ end
198
+ json_response = @backup_jobs_interface.update(backup_job['id'], payload)
199
+ backup_job = json_response['job']
200
+ render_response(json_response, options, 'job') do
201
+ print_green_success "Updated backup job #{backup_job['name']}"
202
+ return _get(backup_job["id"], {}, options)
203
+ end
204
+ return 0, nil
205
+ end
206
+
207
+ def remove(args)
208
+ options = {}
209
+ params = {}
210
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
211
+ opts.banner = subcommand_usage("[job] [options]")
212
+ build_standard_remove_options(opts, options)
213
+ opts.footer = <<-EOT
214
+ Delete a backup job.
215
+ [job] is required. This is the name or id of a backup job.
216
+ EOT
217
+ end
218
+ optparse.parse!(args)
219
+ verify_args!(args:args, optparse:optparse, count:1)
220
+ connect(options)
221
+ backup_job = find_backup_job_by_name_or_id(args[0])
222
+ return 1 if backup_job.nil?
223
+ @backup_jobs_interface.setopts(options)
224
+ if options[:dry_run]
225
+ print_dry_run @backup_jobs_interface.dry.destroy(backup_job['id'], params)
226
+ return
227
+ end
228
+ json_response = @backup_jobs_interface.destroy(backup_job['id'], params)
229
+ render_response(json_response, options) do
230
+ print_green_success "Removed backup job #{backup_job['name']}"
231
+ end
232
+ return 0, nil
233
+ end
234
+
235
+ private
236
+
237
+ def backup_job_column_definitions()
238
+ {
239
+ "ID" => 'id',
240
+ "Name" => 'name',
241
+ "Schedule" => lambda {|it| it['schedule']['name'] rescue '' },
242
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
243
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
244
+ }
245
+ end
246
+
247
+ def add_backup_job_option_types
248
+ [
249
+ {'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
250
+ {'fieldName' => 'code', 'fieldLabel' => 'Code', 'type' => 'text', 'required' => true, 'displayOrder' => 2},
251
+ {'fieldName' => 'retentionCount', 'fieldLabel' => 'Retention Count', 'type' => 'number', 'displayOrder' => 3},
252
+ {'fieldName' => 'scheduleId', 'fieldLabel' => 'Schedule', 'type' => 'select', 'optionSource' => 'executeSchedules', 'displayOrder' => 4}, # should use jobSchedules instead maybe? do we support manual schedules for backups?
253
+ ]
254
+ end
255
+
256
+ def add_backup_job_advanced_option_types
257
+ []
258
+ end
259
+
260
+ def update_backup_job_option_types
261
+ add_backup_job_option_types.collect {|it|
262
+ it.delete('required')
263
+ it.delete('defaultValue')
264
+ it
265
+ }
266
+ end
267
+
268
+ def update_backup_job_advanced_option_types
269
+ add_backup_job_advanced_option_types.collect {|it|
270
+ it.delete('required')
271
+ it.delete('defaultValue')
272
+ it
273
+ }
274
+ end
275
+
276
+ end