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.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/README.md +8 -6
- data/lib/morpheus/api/api_client.rb +32 -14
- data/lib/morpheus/api/auth_interface.rb +4 -2
- data/lib/morpheus/api/backup_jobs_interface.rb +9 -0
- data/lib/morpheus/api/backups_interface.rb +16 -0
- data/lib/morpheus/api/deploy_interface.rb +25 -56
- data/lib/morpheus/api/deployments_interface.rb +43 -54
- data/lib/morpheus/api/doc_interface.rb +57 -0
- data/lib/morpheus/api/instances_interface.rb +5 -0
- data/lib/morpheus/api/rest_interface.rb +40 -0
- data/lib/morpheus/api/user_sources_interface.rb +0 -15
- data/lib/morpheus/api/users_interface.rb +2 -3
- data/lib/morpheus/benchmarking.rb +2 -2
- data/lib/morpheus/cli.rb +3 -1
- data/lib/morpheus/cli/access_token_command.rb +27 -10
- data/lib/morpheus/cli/apps.rb +21 -15
- data/lib/morpheus/cli/backup_jobs_command.rb +276 -0
- data/lib/morpheus/cli/backups_command.rb +271 -0
- data/lib/morpheus/cli/boot_scripts_command.rb +1 -1
- data/lib/morpheus/cli/cli_command.rb +92 -41
- data/lib/morpheus/cli/clusters.rb +0 -18
- data/lib/morpheus/cli/commands/standard/benchmark_command.rb +7 -7
- data/lib/morpheus/cli/commands/standard/man_command.rb +1 -1
- data/lib/morpheus/cli/credentials.rb +13 -9
- data/lib/morpheus/cli/deploy.rb +374 -0
- data/lib/morpheus/cli/deployments.rb +521 -197
- data/lib/morpheus/cli/deploys.rb +271 -126
- data/lib/morpheus/cli/doc.rb +182 -0
- data/lib/morpheus/cli/error_handler.rb +23 -8
- data/lib/morpheus/cli/errors.rb +3 -2
- data/lib/morpheus/cli/image_builder_command.rb +2 -2
- data/lib/morpheus/cli/instances.rb +136 -17
- data/lib/morpheus/cli/invoices_command.rb +51 -38
- data/lib/morpheus/cli/library_layouts_command.rb +1 -1
- data/lib/morpheus/cli/login.rb +9 -3
- data/lib/morpheus/cli/mixins/accounts_helper.rb +158 -100
- data/lib/morpheus/cli/mixins/backups_helper.rb +115 -0
- data/lib/morpheus/cli/mixins/deployments_helper.rb +135 -0
- data/lib/morpheus/cli/mixins/option_source_helper.rb +1 -1
- data/lib/morpheus/cli/mixins/print_helper.rb +110 -74
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +2 -2
- data/lib/morpheus/cli/mixins/whoami_helper.rb +19 -6
- data/lib/morpheus/cli/network_routers_command.rb +1 -1
- data/lib/morpheus/cli/option_parser.rb +48 -5
- data/lib/morpheus/cli/option_types.rb +1 -1
- data/lib/morpheus/cli/remote.rb +3 -2
- data/lib/morpheus/cli/roles.rb +49 -92
- data/lib/morpheus/cli/security_groups.rb +7 -1
- data/lib/morpheus/cli/service_plans_command.rb +10 -10
- data/lib/morpheus/cli/setup.rb +1 -1
- data/lib/morpheus/cli/shell.rb +7 -6
- data/lib/morpheus/cli/subnets_command.rb +1 -1
- data/lib/morpheus/cli/tenants_command.rb +133 -163
- data/lib/morpheus/cli/user_groups_command.rb +20 -65
- data/lib/morpheus/cli/user_settings_command.rb +115 -13
- data/lib/morpheus/cli/user_sources_command.rb +57 -24
- data/lib/morpheus/cli/users.rb +210 -186
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/whitelabel_settings_command.rb +29 -5
- data/lib/morpheus/cli/whoami.rb +113 -6
- data/lib/morpheus/cli/workflows.rb +1 -1
- data/lib/morpheus/ext/hash.rb +21 -0
- data/lib/morpheus/terminal.rb +1 -0
- metadata +12 -3
- 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
|
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])
|
data/lib/morpheus/cli/login.rb
CHANGED
@@ -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
|
57
|
-
The --test option
|
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 "
|
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 "
|
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}
|
64
|
-
|
65
|
-
|
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
|
-
|
119
|
-
print
|
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
|
-
|
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,
|
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
|
-
|
157
|
-
print
|
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
|
216
|
-
|
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
|