morpheus-cli 4.2.16 → 4.2.17

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -652,7 +652,7 @@ EOT
652
652
  connect(options)
653
653
  exit_code, err = 0, nil
654
654
  # if !is_master_account
655
- # print_red_alert "Permissions only available for master account"
655
+ # print_red_alert "Permissions only available for master tenant"
656
656
  # return 1
657
657
  # end
658
658
  layout = find_layout_by_name_or_id(nil, args[0])
@@ -30,7 +30,7 @@ class Morpheus::Cli::Login
30
30
  username, password = nil, nil
31
31
  optparse = Morpheus::Cli::OptionParser.new do |opts|
32
32
  opts.banner = usage
33
- opts.on( '-u', '--username USERNAME', "Username" ) do |val|
33
+ opts.on( '-u', '--username USERNAME', "Username. Sub-tenant users must format their username with a prefix like {subdomain}\\{username}" ) do |val|
34
34
  username = val
35
35
  end
36
36
  opts.on( '-p', '--password PASSWORD', "Password" ) do |val|
@@ -50,11 +50,15 @@ class Morpheus::Cli::Login
50
50
  opts.footer = <<-EOT
51
51
  Login to a remote appliance with a username and password or using an access token.
52
52
  Logging in with username and password will make an authentication api request to obtain an access token.
53
+ [username] is required, this is the username of the Morpheus User
54
+ [password] is required, this is the password of the Morpheus User
55
+ Sub-tenant users will need to pass their tenant subdomain prefix. ie. {subdomain}\\{username}
56
+ By default, the subdomain is the tenant account ID. Example: 2\\neo
53
57
  The --token option can be used to login with a valid access token instead of username and password.
54
58
  The specified token will be verified by making a whoami api request
55
59
  If successful, the access token will be saved with the active session for the remote appliance.
56
- This command will first logout any active session before attempting authorization.
57
- The --test option is available for testing credentials without updating your active session, neithing logging you out or in.
60
+ This command will first logout any active session before attempting authentication.
61
+ The --test option can be used to test credentials without updating the stored credentials for the appliance, neither logging you in or out.
58
62
  EOT
59
63
 
60
64
  end
@@ -106,6 +110,8 @@ EOT
106
110
  if options[:test_only]
107
111
  print green,"Success! Test Credentials verified for #{wallet['username']}", reset, "\n"
108
112
  else
113
+ # clear whoami cache, it will be lazily load_saved_credentials
114
+ ::Morpheus::Cli::Whoami.clear_whoami(@appliance_name, wallet['username'])
109
115
  print green,"Success! Logged in as #{wallet['username']}", reset, "\n"
110
116
  end
111
117
  end
@@ -33,6 +33,43 @@ module Morpheus::Cli::AccountsHelper
33
33
  @roles_interface
34
34
  end
35
35
 
36
+ ## Tenants (Accounts)
37
+
38
+ def account_column_definitions()
39
+ {
40
+ "ID" => 'id',
41
+ "Name" => 'name',
42
+ # "Name" => lambda {|it| it['name'].to_s + (it['master'] ? " (Master Tenant)" : '') },
43
+ "Description" => 'description',
44
+ "Subdomain" => 'subdomain',
45
+ "# Instances" => 'stats.instanceCount',
46
+ "# Users" => 'stats.userCount',
47
+ "Role" => lambda {|it| it['role']['authority'] rescue nil },
48
+ "Master" => lambda {|it| format_boolean(it['master']) },
49
+ "Currency" => 'currency',
50
+ "Status" => lambda {|it|
51
+ status_state = nil
52
+ if it['active']
53
+ status_state = "#{green}ACTIVE#{cyan}"
54
+ else
55
+ status_state = "#{red}INACTIVE#{cyan}"
56
+ end
57
+ status_state
58
+ },
59
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
60
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
61
+ }
62
+ end
63
+
64
+ def list_account_column_definitions()
65
+ columns = account_column_definitions
66
+ columns.delete("Subdomain")
67
+ columns.delete("Master")
68
+ columns.delete("Currency")
69
+ return columns.upcase_keys!
70
+ end
71
+
72
+
36
73
  def find_account_by_name_or_id(val)
37
74
  if val.to_s =~ /\A\d{1,}\Z/
38
75
  return find_account_by_id(val)
@@ -47,7 +84,7 @@ module Morpheus::Cli::AccountsHelper
47
84
  return json_response['account']
48
85
  rescue RestClient::Exception => e
49
86
  if e.response && e.response.code == 404
50
- print_red_alert "Account not found by id #{id}"
87
+ print_red_alert "Tenant not found by id #{id}"
51
88
  else
52
89
  raise e
53
90
  end
@@ -57,12 +94,12 @@ module Morpheus::Cli::AccountsHelper
57
94
  def find_account_by_name(name)
58
95
  accounts = accounts_interface.list({name: name.to_s})['accounts']
59
96
  if accounts.empty?
60
- print_red_alert "Account not found by name #{name}"
97
+ print_red_alert "Tenant not found by name #{name}"
61
98
  return nil
62
99
  elsif accounts.size > 1
63
- print_red_alert "#{accounts.size} accounts found by name #{name}"
64
- print_accounts_table(accounts, {color: red})
65
- print_red_alert "Try using -A ID instead"
100
+ print_red_alert "Found #{accounts.size} tenants by name '#{name}'. Try using ID instead: #{format_list(accounts.collect {|it| it['id']}, 'or', 3)}"
101
+ print "\n"
102
+ print as_pretty_table(accounts, [:id, :name, :description], {color: red, thin: true})
66
103
  print reset,"\n"
67
104
  return nil
68
105
  else
@@ -87,6 +124,35 @@ module Morpheus::Cli::AccountsHelper
87
124
  return account
88
125
  end
89
126
 
127
+ ## Roles
128
+
129
+ def role_column_definitions(options={})
130
+ {
131
+ "ID" => 'id',
132
+ "Name" => 'authority',
133
+ "Description" => 'description',
134
+ #"Scope" => lambda {|it| it['scope'] },
135
+ "Type" => lambda {|it| format_role_type(it) },
136
+ "Multitenant" => lambda {|it|
137
+ format_boolean(it['multitenant']).to_s + (it['multitenantLocked'] ? " (LOCKED)" : "")
138
+ },
139
+ "Owner" => lambda {|it| it['owner'] ? it['owner']['name'] : '' },
140
+ #"Tenant" => lambda {|it| it['account'] ? it['account']['name'] : '' },
141
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
142
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
143
+ }
144
+ end
145
+
146
+ def subtenant_role_column_definitions(options={})
147
+ {
148
+ "ID" => 'id',
149
+ "Name" => 'authority',
150
+ "Description" => 'description',
151
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
152
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
153
+ }
154
+ end
155
+
90
156
  def find_role_by_name_or_id(account_id, val)
91
157
  if val.to_s =~ /\A\d{1,}\Z/
92
158
  return find_role_by_id(account_id, val)
@@ -114,9 +180,11 @@ module Morpheus::Cli::AccountsHelper
114
180
  print_red_alert "Role not found by name #{name}"
115
181
  return nil
116
182
  elsif roles.size > 1
117
- print_red_alert "#{roles.size} roles by name #{name}"
118
- print_roles_table(roles, {color: red, thin: true})
119
- print reset,"\n\n"
183
+ print_red_alert "Found #{roles.size} roles by name '#{name}'. Try using ID instead: #{format_list(roles.collect {|it| it['id']}, 'or', 3)}"
184
+ print "\n"
185
+ # print as_pretty_table(accounts, [:id, :name, :description], {color: red, thin: true})
186
+ print as_pretty_table(roles, {"ID" => 'id', "Name" => 'authority',"Description" => 'description'}.upcase_keys!, {color: red, thin: true})
187
+ print reset,"\n"
120
188
  return nil
121
189
  else
122
190
  return roles[0]
@@ -125,17 +193,57 @@ module Morpheus::Cli::AccountsHelper
125
193
 
126
194
  alias_method :find_role_by_authority, :find_role_by_name
127
195
 
128
- def find_user_by_username_or_id(account_id, val)
196
+
197
+ ## Users
198
+
199
+ def user_column_definitions()
200
+ {
201
+ "ID" => 'id',
202
+ "Tenant" => lambda {|it| it['account'] ? it['account']['name'] : '' },
203
+ "First Name" => 'firstName',
204
+ "Last Name" => 'lastName',
205
+ "Username" => 'username',
206
+ "Email" => 'email',
207
+ "Role" => lambda {|it| format_user_role_names(it) },
208
+ "Notifications" => lambda {|it| it['receiveNotifications'].nil? ? '' : format_boolean(it['receiveNotifications']) },
209
+ "Status" => lambda {|it| format_user_status(it) },
210
+ "Last Login" => lambda {|it| format_duration_ago(it['lastLoginDate']) },
211
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
212
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
213
+ }
214
+ end
215
+
216
+ def list_user_column_definitions()
217
+ columns = user_column_definitions
218
+ columns.delete("Notifications")
219
+ return columns.upcase_keys!
220
+ end
221
+
222
+ def format_user_status(user, return_color=cyan)
223
+ if user["enabled"] != true
224
+ red + "DISABLED" + return_color
225
+ elsif user["accountLocked"]
226
+ red + "ACCOUNT LOCKED" + return_color
227
+ elsif user["accountExpired"]
228
+ yellow + "ACCOUNT EXPIRED" + return_color
229
+ elsif user["passwordExpired"]
230
+ yellow + "PASSWORD EXPIRED" + return_color
231
+ else
232
+ green + "ACTIVE" + return_color
233
+ end
234
+ end
235
+
236
+ def find_user_by_username_or_id(account_id, val, params={})
129
237
  if val.to_s =~ /\A\d{1,}\Z/
130
- return find_user_by_id(account_id, val)
238
+ return find_user_by_id(account_id, val, params)
131
239
  else
132
- return find_user_by_username(account_id, val)
240
+ return find_user_by_username(account_id, val, params)
133
241
  end
134
242
  end
135
243
 
136
- def find_user_by_id(account_id, id)
244
+ def find_user_by_id(account_id, id, params={})
137
245
  begin
138
- json_response = users_interface.get(account_id, id.to_i, {includePermissions:true})
246
+ json_response = users_interface.get(account_id, id.to_i, params)
139
247
  return json_response['user']
140
248
  rescue RestClient::Exception => e
141
249
  if e.response && e.response.code == 404
@@ -146,22 +254,23 @@ module Morpheus::Cli::AccountsHelper
146
254
  end
147
255
  end
148
256
 
149
- def find_user_by_username(account_id, username)
150
- users = users_interface.list(account_id, {username: username.to_s})['users']
257
+ def find_user_by_username(account_id, username, params={})
258
+ users = users_interface.list(account_id, params.merge({username: username.to_s}))['users']
151
259
  if users.empty?
152
260
  print_red_alert "User not found by username #{username}"
153
261
  return nil
154
262
  elsif users.size > 1
155
- print_red_alert "#{users.size} users by username #{username}"
156
- print_users_table(users, {color: red, thin: true})
157
- print reset,"\n\n"
263
+ print_red_alert "Found #{users.size} users by username '#{username}'. Try using ID instead: #{format_list(users.collect {|it| it['id']}, 'or', 3)}"
264
+ print "\n"
265
+ print as_pretty_table(users, list_user_column_definitions, {color: red, thin: true})
266
+ print reset,"\n"
158
267
  return nil
159
268
  else
160
269
  return users[0]
161
270
  end
162
271
  end
163
272
 
164
- def find_all_user_ids(account_id, usernames)
273
+ def find_all_user_ids(account_id, usernames, params={})
165
274
  user_ids = []
166
275
  if usernames.is_a?(String)
167
276
  usernames = usernames.split(",").collect {|it| it.to_s.strip }.select {|it| it }.uniq
@@ -170,11 +279,11 @@ module Morpheus::Cli::AccountsHelper
170
279
  end
171
280
  usernames.each do |username|
172
281
  # save a query
173
- #user = find_user_by_username_or_id(nil, username)
282
+ #user = find_user_by_username_or_id(nil, username, params)
174
283
  if username.to_s =~ /\A\d{1,}\Z/
175
284
  user_ids << username.to_i
176
285
  else
177
- user = find_user_by_username(account_id, username)
286
+ user = find_user_by_username(account_id, username, params)
178
287
  if user.nil?
179
288
  return nil
180
289
  else
@@ -185,6 +294,32 @@ module Morpheus::Cli::AccountsHelper
185
294
  user_ids
186
295
  end
187
296
 
297
+
298
+ ## User Groups
299
+
300
+ def user_group_column_definitions()
301
+ {
302
+ "ID" => lambda {|it| it['id'] },
303
+ #"Account" => lambda {|it| it['account'] ? it['account']['name'] : '' },
304
+ "Name" => lambda {|it| it['name'] },
305
+ "Description" => lambda {|it| it['description'] },
306
+ "Server Group" => lambda {|it| it['serverGroup'] },
307
+ "Sudo Access" => lambda {|it| format_boolean it['sudoAccess'] },
308
+ # "Shared User" => lambda {|it| format_boolean it['sharedUser'] },
309
+ "# Users" => lambda {|it| it['users'].size rescue nil },
310
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
311
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
312
+ }
313
+ end
314
+
315
+ def list_user_group_column_definitions()
316
+ columns = user_group_column_definitions
317
+ columns.delete("Sudo Access")
318
+ columns.delete("Server Group")
319
+ columns.delete("Updated")
320
+ return columns.upcase_keys!
321
+ end
322
+
188
323
  def find_user_group_by_name_or_id(account_id, val)
189
324
  if val.to_s =~ /\A\d{1,}\Z/
190
325
  return find_user_group_by_id(account_id, val)
@@ -212,9 +347,8 @@ module Morpheus::Cli::AccountsHelper
212
347
  print_red_alert "User Group not found by name #{name}"
213
348
  return nil
214
349
  elsif user_groups.size > 1
215
- print_red_alert "#{user_groups.size} user groups found by name #{name}"
216
- print_user_groups_table(user_groups, {color: red})
217
- print_red_alert "Try using ID instead"
350
+ print_red_alert "Found #{user_groups.size} user groups by name '#{name}'. Try using ID instead: #{format_list(user_groups.collect {|it| it['id']}, 'or', 3)}"
351
+ print as_pretty_table(user_groups, [:id, :name, :description], {color: red, thin: true})
218
352
  print reset,"\n"
219
353
  return nil
220
354
  else
@@ -222,36 +356,6 @@ module Morpheus::Cli::AccountsHelper
222
356
  end
223
357
  end
224
358
 
225
- def print_accounts_table(accounts, options={})
226
- table_color = options.key?(:color) ? options[:color] : cyan
227
- rows = accounts.collect do |account|
228
- status_state = nil
229
- if account['active']
230
- status_state = "#{green}ACTIVE#{table_color}"
231
- else
232
- status_state = "#{red}INACTIVE#{table_color}"
233
- end
234
- {
235
- id: account['id'],
236
- name: account['name'],
237
- description: account['description'],
238
- role: account['role'] ? account['role']['authority'] : nil,
239
- status: status_state,
240
- dateCreated: format_local_dt(account['dateCreated'])
241
- }
242
- end
243
- print table_color if table_color
244
- print as_pretty_table(rows, [
245
- :id,
246
- :name,
247
- :description,
248
- :role,
249
- {:dateCreated => {:display_name => "Date Created"} },
250
- :status
251
- ], options.merge({color:table_color}))
252
- print reset if table_color
253
- end
254
-
255
359
  def format_role_type(role)
256
360
  str = ""
257
361
  if role['roleType'] == "account"
@@ -271,52 +375,6 @@ module Morpheus::Cli::AccountsHelper
271
375
  return str
272
376
  end
273
377
 
274
- def print_roles_table(roles, options={})
275
- table_color = options.key?(:color) ? options[:color] : cyan
276
- rows = roles.collect do |role|
277
- {
278
- id: role['id'],
279
- name: role['authority'],
280
- description: role['description'],
281
- scope: role['scope'],
282
- multitenant: role['multitenant'] ? 'Yes' : 'No',
283
- type: format_role_type(role),
284
- owner: role['owner'] ? role['owner']['name'] : "System",
285
- dateCreated: format_local_dt(role['dateCreated'])
286
- }
287
- end
288
- columns = [
289
- :id,
290
- :name,
291
- :description,
292
- # options[:is_master_account] ? :scope : nil,
293
- options[:is_master_account] ? :type : nil,
294
- options[:is_master_account] ? :multitenant : nil,
295
- options[:is_master_account] ? :owner : nil,
296
- {:dateCreated => {:display_name => "Date Created"} }
297
- ].compact
298
- if options[:include_fields]
299
- columns = options[:include_fields]
300
- end
301
- # print table_color if table_color
302
- print as_pretty_table(rows, columns, options)
303
- # print reset if table_color
304
- end
305
-
306
- def print_users_table(users, options={})
307
- table_color = options[:color] || cyan
308
- rows = users.collect do |user|
309
- {id: user['id'], username: user['username'], name: user['displayName'], first: user['firstName'], last: user['lastName'], email: user['email'], role: format_user_role_names(user), account: user['account'] ? user['account']['name'] : nil}
310
- end
311
- columns = [:id, :account, :first, :last, :username, :email, :role]
312
- if options[:include_fields]
313
- columns = options[:include_fields]
314
- end
315
- #print table_color if table_color
316
- print as_pretty_table(rows, columns, options)
317
- #print reset if table_color
318
- end
319
-
320
378
  ## These user access formatted methods should probably move up to PrintHelper to be more ubiquitous.
321
379
 
322
380
  def format_user_role_names(user)
@@ -0,0 +1,115 @@
1
+ require 'morpheus/cli/mixins/print_helper'
2
+ # Mixin for Morpheus::Cli command classes
3
+ # Provides common methods for infrastructure management
4
+ module Morpheus::Cli::BackupsHelper
5
+
6
+ def self.included(klass)
7
+ klass.send :include, Morpheus::Cli::PrintHelper
8
+ end
9
+
10
+ def backups_interface
11
+ # @api_client.groups
12
+ raise "#{self.class} has not defined @backups_interface" if @backups_interface.nil?
13
+ @backups_interface
14
+ end
15
+
16
+ def backup_jobs_interface
17
+ # @api_client.groups
18
+ raise "#{self.class} has not defined @backup_jobs_interface" if @backup_jobs_interface.nil?
19
+ @backup_jobs_interface
20
+ end
21
+
22
+ def backup_object_key
23
+ 'backup'
24
+ end
25
+
26
+ def backup_list_key
27
+ 'backups'
28
+ end
29
+
30
+ def find_backup_by_name_or_id(val)
31
+ if val.to_s =~ /\A\d{1,}\Z/
32
+ return find_backup_by_id(val)
33
+ else
34
+ return find_backup_by_name(val)
35
+ end
36
+ end
37
+
38
+ def find_backup_by_id(id)
39
+ begin
40
+ json_response = backups_interface.get(id.to_i)
41
+ return json_response[backup_object_key]
42
+ rescue RestClient::Exception => e
43
+ if e.response && e.response.code == 404
44
+ print_red_alert "Backup not found by id '#{id}'"
45
+ else
46
+ raise e
47
+ end
48
+ end
49
+ end
50
+
51
+ def find_backup_by_name(name)
52
+ json_response = backups_interface.list({name: name.to_s})
53
+ backups = json_response[backup_list_key]
54
+ if backups.empty?
55
+ print_red_alert "Backup not found by name '#{name}'"
56
+ return nil
57
+ elsif backups.size > 1
58
+ print_red_alert "#{backups.size} backups found by name '#{name}'"
59
+ puts_error as_pretty_table(backups, [:id, :name], {color:red})
60
+ print_red_alert "Try using ID instead"
61
+ print reset,"\n"
62
+ return nil
63
+ else
64
+ return backups[0]
65
+ end
66
+ end
67
+
68
+ def backup_job_object_key
69
+ # 'backupJob'
70
+ 'job'
71
+ end
72
+
73
+ def backup_job_list_key
74
+ # 'backupJobs'
75
+ 'jobs'
76
+ end
77
+
78
+ def find_backup_job_by_name_or_id(val)
79
+ if val.to_s =~ /\A\d{1,}\Z/
80
+ return find_backup_job_by_id(val)
81
+ else
82
+ return find_backup_job_by_name(val)
83
+ end
84
+ end
85
+
86
+ def find_backup_job_by_id(id)
87
+ begin
88
+ json_response = backup_jobs_interface.get(id.to_i)
89
+ return json_response[backup_job_object_key]
90
+ rescue RestClient::Exception => e
91
+ if e.response && e.response.code == 404
92
+ print_red_alert "Backup job not found by id '#{id}'"
93
+ else
94
+ raise e
95
+ end
96
+ end
97
+ end
98
+
99
+ def find_backup_job_by_name(name)
100
+ json_response = backup_jobs_interface.list({name: name.to_s})
101
+ backup_jobs = json_response[backup_job_list_key]
102
+ if backup_jobs.empty?
103
+ print_red_alert "Backup job not found by name '#{name}'"
104
+ return nil
105
+ elsif backup_jobs.size > 1
106
+ print_red_alert "#{backup_jobs.size} backup jobs found by name '#{name}'"
107
+ puts_error as_pretty_table(backup_jobs, [:id, :name], {color:red})
108
+ print_red_alert "Try using ID instead"
109
+ print reset,"\n"
110
+ return nil
111
+ else
112
+ return backup_jobs[0]
113
+ end
114
+ end
115
+ end