morpheus-cli 2.10.0 → 2.10.1
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/bin/morpheus +27 -32
- data/lib/morpheus/api/accounts_interface.rb +36 -47
- data/lib/morpheus/api/api_client.rb +141 -110
- data/lib/morpheus/api/app_templates_interface.rb +56 -72
- data/lib/morpheus/api/apps_interface.rb +111 -132
- data/lib/morpheus/api/auth_interface.rb +30 -0
- data/lib/morpheus/api/clouds_interface.rb +71 -76
- data/lib/morpheus/api/custom_instance_types_interface.rb +21 -46
- data/lib/morpheus/api/dashboard_interface.rb +10 -17
- data/lib/morpheus/api/deploy_interface.rb +60 -72
- data/lib/morpheus/api/deployments_interface.rb +53 -71
- data/lib/morpheus/api/groups_interface.rb +55 -45
- data/lib/morpheus/api/instance_types_interface.rb +19 -23
- data/lib/morpheus/api/instances_interface.rb +179 -177
- data/lib/morpheus/api/key_pairs_interface.rb +11 -17
- data/lib/morpheus/api/license_interface.rb +18 -23
- data/lib/morpheus/api/load_balancers_interface.rb +54 -69
- data/lib/morpheus/api/logs_interface.rb +25 -29
- data/lib/morpheus/api/options_interface.rb +13 -17
- data/lib/morpheus/api/provision_types_interface.rb +19 -22
- data/lib/morpheus/api/roles_interface.rb +75 -94
- data/lib/morpheus/api/security_group_rules_interface.rb +28 -37
- data/lib/morpheus/api/security_groups_interface.rb +39 -51
- data/lib/morpheus/api/servers_interface.rb +113 -115
- data/lib/morpheus/api/setup_interface.rb +31 -0
- data/lib/morpheus/api/task_sets_interface.rb +36 -38
- data/lib/morpheus/api/tasks_interface.rb +56 -69
- data/lib/morpheus/api/users_interface.rb +67 -76
- data/lib/morpheus/api/virtual_images_interface.rb +61 -61
- data/lib/morpheus/api/whoami_interface.rb +12 -15
- data/lib/morpheus/cli.rb +71 -60
- data/lib/morpheus/cli/accounts.rb +254 -315
- data/lib/morpheus/cli/alias_command.rb +219 -0
- data/lib/morpheus/cli/app_templates.rb +264 -272
- data/lib/morpheus/cli/apps.rb +608 -671
- data/lib/morpheus/cli/cli_command.rb +259 -21
- data/lib/morpheus/cli/cli_registry.rb +99 -14
- data/lib/morpheus/cli/clouds.rb +599 -372
- data/lib/morpheus/cli/config_file.rb +126 -0
- data/lib/morpheus/cli/credentials.rb +141 -117
- data/lib/morpheus/cli/dashboard_command.rb +48 -56
- data/lib/morpheus/cli/deployments.rb +254 -268
- data/lib/morpheus/cli/deploys.rb +150 -142
- data/lib/morpheus/cli/error_handler.rb +38 -0
- data/lib/morpheus/cli/groups.rb +551 -179
- data/lib/morpheus/cli/hosts.rb +862 -617
- data/lib/morpheus/cli/instance_types.rb +103 -95
- data/lib/morpheus/cli/instances.rb +1335 -1009
- data/lib/morpheus/cli/key_pairs.rb +82 -90
- data/lib/morpheus/cli/library.rb +498 -499
- data/lib/morpheus/cli/license.rb +83 -101
- data/lib/morpheus/cli/load_balancers.rb +314 -300
- data/lib/morpheus/cli/login.rb +66 -44
- data/lib/morpheus/cli/logout.rb +47 -46
- data/lib/morpheus/cli/mixins/accounts_helper.rb +69 -31
- data/lib/morpheus/cli/mixins/infrastructure_helper.rb +106 -0
- data/lib/morpheus/cli/mixins/print_helper.rb +181 -17
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +535 -458
- data/lib/morpheus/cli/mixins/whoami_helper.rb +2 -2
- data/lib/morpheus/cli/option_parser.rb +35 -0
- data/lib/morpheus/cli/option_types.rb +232 -192
- data/lib/morpheus/cli/recent_activity_command.rb +61 -65
- data/lib/morpheus/cli/remote.rb +446 -199
- data/lib/morpheus/cli/roles.rb +884 -906
- data/lib/morpheus/cli/security_group_rules.rb +213 -203
- data/lib/morpheus/cli/security_groups.rb +237 -192
- data/lib/morpheus/cli/shell.rb +338 -231
- data/lib/morpheus/cli/tasks.rb +326 -308
- data/lib/morpheus/cli/users.rb +457 -462
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/version_command.rb +16 -18
- data/lib/morpheus/cli/virtual_images.rb +526 -345
- data/lib/morpheus/cli/whoami.rb +125 -111
- data/lib/morpheus/cli/workflows.rb +338 -185
- data/lib/morpheus/formatters.rb +8 -1
- data/lib/morpheus/logging.rb +1 -1
- data/lib/morpheus/rest_client.rb +17 -8
- metadata +9 -3
- data/lib/morpheus/api/custom_instance_types.rb +0 -55
@@ -9,55 +9,31 @@ require 'json'
|
|
9
9
|
class Morpheus::Cli::KeyPairs
|
10
10
|
include Morpheus::Cli::CliCommand
|
11
11
|
include Morpheus::Cli::AccountsHelper
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
register_subcommands :list, :get, :add, :update, :remove
|
13
|
+
alias_subcommand :details, :get
|
14
|
+
|
15
|
+
def initialize()
|
16
|
+
# @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
15
17
|
end
|
16
18
|
|
17
19
|
def connect(opts)
|
18
|
-
@
|
19
|
-
if @access_token.empty?
|
20
|
-
print_red_alert "Invalid Credentials. Unable to acquire access token. Please verify your credentials and try again."
|
21
|
-
exit 1
|
22
|
-
end
|
23
|
-
@api_client = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url)
|
20
|
+
@api_client = establish_remote_appliance_connection(opts)
|
24
21
|
@accounts_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).accounts
|
25
22
|
@key_pairs_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).key_pairs
|
26
23
|
end
|
27
24
|
|
28
25
|
def handle(args)
|
29
|
-
|
30
|
-
if args.empty?
|
31
|
-
puts "\n#{usage}\n\n"
|
32
|
-
exit 1
|
33
|
-
end
|
34
|
-
|
35
|
-
case args[0]
|
36
|
-
when 'list'
|
37
|
-
list(args[1..-1])
|
38
|
-
when 'details'
|
39
|
-
details(args[1..-1])
|
40
|
-
when 'add'
|
41
|
-
add(args[1..-1])
|
42
|
-
when 'update'
|
43
|
-
update(args[1..-1])
|
44
|
-
when 'remove'
|
45
|
-
remove(args[1..-1])
|
46
|
-
else
|
47
|
-
puts "\n#{usage}\n\n"
|
48
|
-
exit 127
|
49
|
-
end
|
26
|
+
handle_subcommand(args)
|
50
27
|
end
|
51
28
|
|
52
29
|
def list(args)
|
53
|
-
usage = "Usage: morpheus key-pairs list [options]"
|
54
30
|
options = {}
|
55
31
|
params = {}
|
56
32
|
optparse = OptionParser.new do|opts|
|
57
|
-
opts.banner =
|
33
|
+
opts.banner = subcommand_usage()
|
58
34
|
build_common_options(opts, options, [:account, :list, :json])
|
59
35
|
end
|
60
|
-
optparse.parse(args)
|
36
|
+
optparse.parse!(args)
|
61
37
|
connect(options)
|
62
38
|
begin
|
63
39
|
|
@@ -74,13 +50,23 @@ class Morpheus::Cli::KeyPairs
|
|
74
50
|
print JSON.pretty_generate(json_response)
|
75
51
|
print "\n"
|
76
52
|
else
|
77
|
-
|
53
|
+
title = "Morpheus Hosts"
|
54
|
+
subtitles = []
|
55
|
+
if account
|
56
|
+
subtitles << "Account: #{account['name']}".strip
|
57
|
+
end
|
58
|
+
if params[:phrase]
|
59
|
+
subtitles << "Search: #{params[:phrase]}".strip
|
60
|
+
end
|
61
|
+
subtitle = subtitles.join(', ')
|
62
|
+
print "\n" ,cyan, bold, title, (subtitle.empty? ? "" : " - #{subtitle}"), "\n", "==================", reset, "\n\n"
|
78
63
|
if key_pairs.empty?
|
79
64
|
puts yellow,"No key pairs found.",reset
|
80
65
|
else
|
81
66
|
print_key_pairs_table(key_pairs)
|
67
|
+
print_results_pagination(json_response)
|
82
68
|
end
|
83
|
-
print reset,"\n
|
69
|
+
print reset,"\n"
|
84
70
|
end
|
85
71
|
rescue RestClient::Exception => e
|
86
72
|
print_rest_exception(e, options)
|
@@ -88,33 +74,26 @@ class Morpheus::Cli::KeyPairs
|
|
88
74
|
end
|
89
75
|
end
|
90
76
|
|
91
|
-
def
|
92
|
-
usage = "Usage: morpheus key-pairs details [name] [options]"
|
77
|
+
def get(args)
|
93
78
|
options = {}
|
94
79
|
params = {}
|
95
80
|
optparse = OptionParser.new do|opts|
|
96
|
-
opts.banner =
|
81
|
+
opts.banner = subcommand_usage("[name]")
|
97
82
|
build_common_options(opts, options, [:account, :json])
|
98
83
|
end
|
99
|
-
optparse.parse(args)
|
84
|
+
optparse.parse!(args)
|
100
85
|
|
101
86
|
if args.count < 1
|
102
|
-
puts
|
87
|
+
puts optparse
|
103
88
|
exit 1
|
104
89
|
end
|
105
|
-
name = args[0]
|
106
90
|
|
107
91
|
connect(options)
|
108
92
|
begin
|
109
|
-
|
110
93
|
account = find_account_from_options(options)
|
111
94
|
account_id = account ? account['id'] : nil
|
112
95
|
|
113
|
-
|
114
|
-
# there may be response data outside of account that needs to be displayed
|
115
|
-
|
116
|
-
# allow finding by ID since name is not unique!
|
117
|
-
key_pair = ((name.to_s =~ /\A\d{1,}\Z/) ? find_key_pair_by_id(account_id, name) : find_key_pair_by_name(account_id, name) )
|
96
|
+
key_pair = find_key_pair_by_name_or_id(account_id, args[0])
|
118
97
|
exit 1 if key_pair.nil?
|
119
98
|
|
120
99
|
if options[:json]
|
@@ -128,7 +107,7 @@ class Morpheus::Cli::KeyPairs
|
|
128
107
|
puts "MD5: #{key_pair['md5']}"
|
129
108
|
puts "Date Created: #{format_local_dt(key_pair['dateCreated'])}"
|
130
109
|
#puts "Last Updated: #{format_local_dt(key_pair['lastUpdated'])}"
|
131
|
-
print reset,"\n
|
110
|
+
print reset,"\n"
|
132
111
|
|
133
112
|
# todo: show public key
|
134
113
|
|
@@ -142,8 +121,7 @@ class Morpheus::Cli::KeyPairs
|
|
142
121
|
def add(args)
|
143
122
|
options = {}
|
144
123
|
optparse = OptionParser.new do|opts|
|
145
|
-
opts.banner = "
|
146
|
-
|
124
|
+
opts.banner = subcommand_usage("[name] [options]")
|
147
125
|
opts.on('', '--public-key-file FILENAME', "Public Key File" ) do |filename|
|
148
126
|
if File.exists?(File.expand_path(filename))
|
149
127
|
options['publicKey'] = File.read(File.expand_path(filename))
|
@@ -178,19 +156,19 @@ class Morpheus::Cli::KeyPairs
|
|
178
156
|
options[:options]['privateKey'] = options['privateKey']
|
179
157
|
end
|
180
158
|
|
181
|
-
build_common_options(opts, options, [:account, :options, :json])
|
159
|
+
build_common_options(opts, options, [:account, :options, :json, :dry_run])
|
182
160
|
end
|
183
|
-
|
184
|
-
if args.count < 1
|
185
|
-
|
186
|
-
|
161
|
+
optparse.parse!(args)
|
162
|
+
# if args.count < 1
|
163
|
+
# puts optparse
|
164
|
+
# exit 1
|
165
|
+
# end
|
166
|
+
if args[0]
|
167
|
+
options[:options] ||= {}
|
168
|
+
options[:options]['name'] ||= args[0]
|
187
169
|
end
|
188
|
-
optparse.parse(args)
|
189
|
-
|
190
170
|
connect(options)
|
191
|
-
|
192
171
|
begin
|
193
|
-
|
194
172
|
account = find_account_from_options(options)
|
195
173
|
account_id = account ? account['id'] : nil
|
196
174
|
|
@@ -203,12 +181,15 @@ class Morpheus::Cli::KeyPairs
|
|
203
181
|
print_red_alert "privateKey is required"
|
204
182
|
exit 1
|
205
183
|
end
|
206
|
-
params['name'] = args[0]
|
184
|
+
#params['name'] = args[0]
|
207
185
|
|
208
186
|
key_pair_payload = params.select {|k,v| ['name','publicKey', 'privateKey'].include?(k) }
|
209
|
-
|
210
|
-
|
211
|
-
|
187
|
+
payload = {keyPair: key_pair_payload}
|
188
|
+
if options[:dry_run]
|
189
|
+
print_dry_run @key_pairs_interface.dry.create(account_id, payload)
|
190
|
+
return
|
191
|
+
end
|
192
|
+
json_response = @key_pairs_interface.create(account_id, payload)
|
212
193
|
if options[:json]
|
213
194
|
print JSON.pretty_generate(json_response)
|
214
195
|
print "\n"
|
@@ -222,43 +203,44 @@ class Morpheus::Cli::KeyPairs
|
|
222
203
|
end
|
223
204
|
|
224
205
|
def update(args)
|
225
|
-
usage = "Usage: morpheus key-pairs update [name] [options]"
|
226
206
|
options = {}
|
227
207
|
optparse = OptionParser.new do|opts|
|
228
|
-
opts.banner =
|
229
|
-
build_common_options(opts, options, [:account, :options, :json])
|
208
|
+
opts.banner = subcommand_usage("[name] [options]")
|
209
|
+
build_common_options(opts, options, [:account, :options, :json, :dry_run])
|
230
210
|
end
|
231
|
-
optparse.parse(args)
|
211
|
+
optparse.parse!(args)
|
232
212
|
|
233
213
|
if args.count < 1
|
234
|
-
puts
|
214
|
+
puts optparse
|
235
215
|
exit 1
|
236
216
|
end
|
237
|
-
name = args[0]
|
238
217
|
|
239
218
|
connect(options)
|
240
|
-
|
241
219
|
begin
|
242
220
|
|
243
221
|
account = find_account_from_options(options)
|
244
222
|
account_id = account ? account['id'] : nil
|
245
223
|
|
246
|
-
key_pair = (
|
224
|
+
key_pair = find_key_pair_by_name_or_id(account_id, args[0])
|
247
225
|
exit 1 if key_pair.nil?
|
248
226
|
|
249
227
|
#params = Morpheus::Cli::OptionTypes.prompt(update_key_pair_option_types, options[:options], @api_client, options[:params])
|
250
228
|
params = options[:options] || {}
|
251
229
|
|
252
230
|
if params.empty?
|
253
|
-
puts
|
231
|
+
puts optparse
|
254
232
|
option_lines = update_key_pair_option_types.collect {|it| "\t-O #{it['fieldName']}=\"value\"" }.join("\n")
|
255
233
|
puts "\nAvailable Options:\n#{option_lines}\n\n"
|
256
234
|
exit 1
|
257
235
|
end
|
258
236
|
|
259
237
|
key_pair_payload = params.select {|k,v| ['name'].include?(k) }
|
260
|
-
|
261
|
-
|
238
|
+
payload = {keyPair: key_pair_payload}
|
239
|
+
if options[:dry_run]
|
240
|
+
print_dry_run @key_pairs_interface.dry.update(account_id, key_pair['id'], payload)
|
241
|
+
return
|
242
|
+
end
|
243
|
+
json_response = @key_pairs_interface.update(account_id, key_pair['id'], payload)
|
262
244
|
if options[:json]
|
263
245
|
print JSON.pretty_generate(json_response)
|
264
246
|
print "\n"
|
@@ -272,19 +254,17 @@ class Morpheus::Cli::KeyPairs
|
|
272
254
|
end
|
273
255
|
|
274
256
|
def remove(args)
|
275
|
-
usage = "Usage: morpheus key-pairs remove [name]"
|
276
257
|
options = {}
|
277
258
|
optparse = OptionParser.new do|opts|
|
278
|
-
opts.banner =
|
279
|
-
build_common_options(opts, options, [:account, :auto_confirm, :json])
|
259
|
+
opts.banner = subcommand_usage("[name]")
|
260
|
+
build_common_options(opts, options, [:account, :auto_confirm, :json, :dry_run])
|
280
261
|
end
|
281
|
-
optparse.parse(args)
|
262
|
+
optparse.parse!(args)
|
282
263
|
|
283
264
|
if args.count < 1
|
284
|
-
puts
|
265
|
+
puts optparse
|
285
266
|
exit 1
|
286
267
|
end
|
287
|
-
name = args[0]
|
288
268
|
|
289
269
|
connect(options)
|
290
270
|
begin
|
@@ -292,11 +272,16 @@ class Morpheus::Cli::KeyPairs
|
|
292
272
|
account = find_account_from_options(options)
|
293
273
|
account_id = account ? account['id'] : nil
|
294
274
|
# allow finding by ID since name is not unique!
|
295
|
-
key_pair = (
|
275
|
+
key_pair = find_key_pair_by_name_or_id(account_id, args[0])
|
296
276
|
exit 1 if key_pair.nil?
|
277
|
+
|
297
278
|
unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the key pair #{key_pair['name']}?")
|
298
279
|
exit
|
299
280
|
end
|
281
|
+
if options[:dry_run]
|
282
|
+
print_dry_run @key_pairs_interface.dry.destroy(account_id, key_pair['id'])
|
283
|
+
return
|
284
|
+
end
|
300
285
|
json_response = @key_pairs_interface.destroy(account_id, key_pair['id'])
|
301
286
|
if options[:json]
|
302
287
|
print JSON.pretty_generate(json_response)
|
@@ -311,8 +296,15 @@ class Morpheus::Cli::KeyPairs
|
|
311
296
|
end
|
312
297
|
end
|
313
298
|
|
314
|
-
private
|
315
|
-
|
299
|
+
private
|
300
|
+
def find_key_pair_by_name_or_id(account_id, val)
|
301
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
302
|
+
return find_key_pair_by_id(account_id, val)
|
303
|
+
else
|
304
|
+
return find_key_pair_by_name(account_id, val)
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
316
308
|
def find_key_pair_by_id(account_id, id)
|
317
309
|
raise "#{self.class} has not defined @key_pairs_interface" if @key_pairs_interface.nil?
|
318
310
|
begin
|
@@ -336,7 +328,7 @@ private
|
|
336
328
|
elsif key_pairs.size > 1
|
337
329
|
print_red_alert "#{key_pairs.size} key_pairs by name #{name}"
|
338
330
|
print_key_pairs_table(key_pairs, {color: red})
|
339
|
-
print reset,"\n
|
331
|
+
print reset,"\n"
|
340
332
|
return nil
|
341
333
|
else
|
342
334
|
return key_pairs[0]
|
@@ -347,17 +339,16 @@ private
|
|
347
339
|
table_color = opts[:color] || cyan
|
348
340
|
rows = key_pairs.collect do |key_pair|
|
349
341
|
{
|
350
|
-
id: key_pair['id'],
|
351
|
-
name: key_pair['name'],
|
342
|
+
id: key_pair['id'],
|
343
|
+
name: key_pair['name'],
|
352
344
|
md5: key_pair['md5'],
|
353
|
-
dateCreated: format_local_dt(key_pair['dateCreated'])
|
345
|
+
dateCreated: format_local_dt(key_pair['dateCreated'])
|
354
346
|
}
|
355
347
|
end
|
356
|
-
|
357
348
|
print table_color
|
358
349
|
tp rows, [
|
359
|
-
:id,
|
360
|
-
:name,
|
350
|
+
:id,
|
351
|
+
:name,
|
361
352
|
:md5,
|
362
353
|
{:dateCreated => {:display_name => "Date Created"} }
|
363
354
|
]
|
@@ -367,6 +358,7 @@ private
|
|
367
358
|
|
368
359
|
def add_key_pair_option_types
|
369
360
|
[
|
361
|
+
{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
|
370
362
|
{'fieldName' => 'publicKey', 'fieldLabel' => 'Public Key', 'type' => 'text', 'required' => true, 'displayOrder' => 2},
|
371
363
|
{'fieldName' => 'privateKey', 'fieldLabel' => 'Private Key', 'type' => 'text', 'required' => true, 'displayOrder' => 3},
|
372
364
|
]
|
data/lib/morpheus/cli/library.rb
CHANGED
@@ -6,496 +6,499 @@ require 'morpheus/cli/cli_command'
|
|
6
6
|
class Morpheus::Cli::Library
|
7
7
|
include Morpheus::Cli::CliCommand
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
instance_type_payload = params.select {|k,v| instance_type_keys.include?(k) }
|
139
|
-
logo_file = nil
|
140
|
-
if params['logo']
|
141
|
-
filename = File.expand_path(params['logo'])
|
142
|
-
if !File.exists?(filename)
|
143
|
-
print_red_alert "File not found: #{filename}"
|
9
|
+
register_subcommands :list, :get, :add, :update, :remove, :'add-version'
|
10
|
+
alias_subcommand :details, :get
|
11
|
+
|
12
|
+
def initialize()
|
13
|
+
# @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
|
14
|
+
end
|
15
|
+
|
16
|
+
def connect(opts)
|
17
|
+
@api_client = establish_remote_appliance_connection(opts)
|
18
|
+
@custom_instance_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).custom_instance_types
|
19
|
+
@provision_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).provision_types
|
20
|
+
end
|
21
|
+
|
22
|
+
def handle(args)
|
23
|
+
handle_subcommand(args)
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
def list(args)
|
28
|
+
options = {}
|
29
|
+
optparse = OptionParser.new do|opts|
|
30
|
+
opts.banner = subcommand_usage()
|
31
|
+
build_common_options(opts, options, [:list, :dry_run, :json])
|
32
|
+
end
|
33
|
+
optparse.parse!(args)
|
34
|
+
connect(options)
|
35
|
+
begin
|
36
|
+
params = {}
|
37
|
+
[:phrase, :offset, :max, :sort, :direction].each do |k|
|
38
|
+
params[k] = options[k] unless options[k].nil?
|
39
|
+
end
|
40
|
+
|
41
|
+
if options[:dry_run]
|
42
|
+
print_dry_run @custom_instance_types_interface.dry.list(params)
|
43
|
+
return
|
44
|
+
end
|
45
|
+
|
46
|
+
json_response = @custom_instance_types_interface.list(params)
|
47
|
+
|
48
|
+
if options[:json]
|
49
|
+
print JSON.pretty_generate(json_response), "\n"
|
50
|
+
return
|
51
|
+
end
|
52
|
+
|
53
|
+
instance_types = json_response['instanceTypes']
|
54
|
+
print "\n" ,cyan, bold, "Morpheus Custom Instance Types\n","==================", reset, "\n\n"
|
55
|
+
if instance_types.empty?
|
56
|
+
puts yellow,"No instance types currently configured.",reset
|
57
|
+
else
|
58
|
+
instance_types.each do |instance_type|
|
59
|
+
versions = instance_type['versions'].join(', ')
|
60
|
+
print cyan, "= #{instance_type['name']} (#{instance_type['code']}) - #{versions}\n"
|
61
|
+
instance_type['instanceTypeLayouts'].each do |layout|
|
62
|
+
print green, " - #{layout['name']}\n",reset
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
print reset,"\n"
|
67
|
+
rescue RestClient::Exception => e
|
68
|
+
print_rest_exception(e, options)
|
69
|
+
exit 1
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def get(args)
|
74
|
+
options = {}
|
75
|
+
optparse = OptionParser.new do|opts|
|
76
|
+
opts.banner = subcommand_usage("[name]")
|
77
|
+
build_common_options(opts, options, [:json, :dry_run])
|
78
|
+
end
|
79
|
+
optparse.parse!(args)
|
80
|
+
if args.count < 1
|
81
|
+
puts optparse
|
82
|
+
exit 1
|
83
|
+
end
|
84
|
+
|
85
|
+
connect(options)
|
86
|
+
begin
|
87
|
+
if options[:dry_run]
|
88
|
+
if args[0] =~ /code:/
|
89
|
+
print_dry_run @custom_instance_types_interface.dry.list({code: args[0]})
|
90
|
+
else
|
91
|
+
print_dry_run @custom_instance_types_interface.dry.list({name: args[0]})
|
92
|
+
end
|
93
|
+
return
|
94
|
+
end
|
95
|
+
instance_type = find_custom_instance_type_by_name_or_code(args[0])
|
96
|
+
exit 1 if instance_type.nil?
|
97
|
+
|
98
|
+
if options[:json]
|
99
|
+
print JSON.pretty_generate({instanceType: instance_type}), "\n"
|
100
|
+
return
|
101
|
+
end
|
102
|
+
|
103
|
+
if instance_type.nil?
|
104
|
+
puts yellow,"No custom instance type found by name #{name}.",reset
|
105
|
+
else
|
106
|
+
print "\n" ,cyan, bold, "Custom Instance Type Details\n","==================", reset, "\n\n"
|
107
|
+
versions = instance_type['versions'].join(', ')
|
108
|
+
print cyan, "= #{instance_type['name']} (#{instance_type['code']}) - #{versions}\n"
|
109
|
+
instance_type['instanceTypeLayouts'].each do |layout|
|
110
|
+
print green, " - #{layout['name']}\n",reset
|
111
|
+
end
|
112
|
+
print reset,"\n"
|
113
|
+
end
|
114
|
+
|
115
|
+
rescue RestClient::Exception => e
|
116
|
+
print_rest_exception(e, options)
|
117
|
+
exit 1
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def add(args)
|
122
|
+
options = {}
|
123
|
+
optparse = OptionParser.new do|opts|
|
124
|
+
opts.banner = subcommand_usage()
|
125
|
+
build_common_options(opts, options, [:options, :json, :dry_run])
|
126
|
+
end
|
127
|
+
optparse.parse!(args)
|
128
|
+
connect(options)
|
129
|
+
begin
|
130
|
+
params = Morpheus::Cli::OptionTypes.prompt(add_instance_type_option_types, options[:options], @api_client, options[:params])
|
131
|
+
instance_type_keys = ['name', 'description', 'category', 'visibility', 'environmentPrefix']
|
132
|
+
instance_type_payload = params.select {|k,v| instance_type_keys.include?(k) }
|
133
|
+
logo_file = nil
|
134
|
+
if params['logo']
|
135
|
+
filename = File.expand_path(params['logo'])
|
136
|
+
if !File.exists?(filename)
|
137
|
+
print_red_alert "File not found: #{filename}"
|
144
138
|
exit 1
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
139
|
+
end
|
140
|
+
#instance_type_payload['logo'] = File.new(filename, 'rb')
|
141
|
+
logo_file = File.new(filename, 'rb')
|
142
|
+
end
|
143
|
+
if params['hasAutoScale'] == 'on'
|
144
|
+
instance_type_payload['hasAutoScale'] = true
|
145
|
+
end
|
146
|
+
if params['hasDeployment'] == 'on'
|
147
|
+
instance_type_payload['hasDeployment'] = true
|
148
|
+
end
|
149
|
+
payload = {instanceType: instance_type_payload}
|
150
|
+
if options[:dry_run]
|
151
|
+
print_dry_run @custom_instance_types_interface.dry.create(payload)
|
152
|
+
if logo_file
|
153
|
+
print_dry_run @custom_instance_types_interface.dry.update_logo(":id", logo_file)
|
154
|
+
end
|
155
|
+
return
|
156
|
+
end
|
157
|
+
json_response = @custom_instance_types_interface.create(payload)
|
158
|
+
|
159
|
+
if json_response['success']
|
160
|
+
if logo_file
|
161
|
+
begin
|
162
|
+
@custom_instance_types_interface.update_logo(json_response['instanceType']['id'], logo_file)
|
163
|
+
rescue RestClient::Exception => e
|
164
|
+
print_red_alert "Failed to save logo!"
|
165
|
+
print_rest_exception(e, options)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
if options[:json]
|
171
|
+
print JSON.pretty_generate(json_response), "\n"
|
172
|
+
return
|
173
|
+
end
|
174
|
+
|
175
|
+
print_green_success "Added Instance Type #{instance_type_payload['name']}"
|
176
|
+
unless options[:no_prompt]
|
177
|
+
if ::Morpheus::Cli::OptionTypes::confirm("Add first version?", options)
|
178
|
+
puts "\n"
|
179
|
+
add_version(["code:#{json_response['code']}"])
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
#list([])
|
184
|
+
|
185
|
+
rescue RestClient::Exception => e
|
186
|
+
print_rest_exception(e, options)
|
187
|
+
exit 1
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def update(args)
|
192
|
+
options = {}
|
193
|
+
optparse = OptionParser.new do|opts|
|
194
|
+
opts.banner = subcommand_usage("[name] [options]")
|
195
|
+
build_common_options(opts, options, [:options, :json, :dry_run])
|
196
|
+
end
|
197
|
+
optparse.parse!(args)
|
198
|
+
if args.count < 1
|
199
|
+
puts optparse
|
200
|
+
exit 1
|
201
|
+
end
|
202
|
+
connect(options)
|
203
|
+
begin
|
204
|
+
instance_type = find_custom_instance_type_by_name_or_code(args[0])
|
205
|
+
exit 1 if instance_type.nil?
|
206
|
+
# option_types = update_instance_type_option_types(instance_type)
|
207
|
+
# params = Morpheus::Cli::OptionTypes.prompt(option_types, options[:options], @api_client, options[:params])
|
208
|
+
params = options[:options] || {}
|
209
|
+
instance_type_keys = ['name', 'description', 'category', 'visibility', 'environmentPrefix']
|
210
|
+
instance_type_payload = params.select {|k,v| instance_type_keys.include?(k) }
|
211
|
+
logo_file = nil
|
212
|
+
if params['logo']
|
213
|
+
filename = File.expand_path(params['logo'])
|
214
|
+
if !File.exists?(filename)
|
215
|
+
print_red_alert "File not found: #{filename}"
|
217
216
|
exit 1
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
217
|
+
end
|
218
|
+
#instance_type_payload['logo'] = File.new(filename, 'rb')
|
219
|
+
logo_file = File.new(filename, 'rb')
|
220
|
+
end
|
221
|
+
if params['hasAutoScale'] == 'on'
|
222
|
+
instance_type_payload['hasAutoScale'] = true
|
223
|
+
elsif params['hasAutoScale'] == 'off'
|
224
|
+
instance_type_payload['hasAutoScale'] = false
|
225
|
+
end
|
226
|
+
if params['hasDeployment'] == 'on'
|
227
|
+
instance_type_payload['hasDeployment'] = true
|
228
|
+
elsif params['hasDeployment'] == 'off'
|
229
|
+
instance_type_payload['hasDeployment'] = false
|
230
|
+
end
|
231
|
+
if instance_type_payload.empty? && logo_file.nil?
|
232
|
+
puts optparse
|
233
|
+
option_lines = update_instance_type_option_types.collect {|it| "\t-O #{it['fieldName']}=\"value\"" }.join("\n")
|
234
|
+
puts "\nAvailable Options:\n#{option_lines}\n\n"
|
235
|
+
exit 1
|
236
|
+
end
|
237
|
+
if instance_type_payload.empty?
|
238
|
+
# just updating logo (separate request)
|
239
|
+
instance_type_payload['name'] = instance_type['name']
|
240
|
+
end
|
241
|
+
payload = {instanceType: instance_type_payload}
|
242
|
+
if options[:dry_run]
|
243
|
+
print_dry_run @custom_instance_types_interface.dry.update(instance_type['id'], payload)
|
244
|
+
if logo_file
|
245
|
+
print_dry_run @custom_instance_types_interface.dry.update_logo(":id", logo_file)
|
246
|
+
end
|
247
|
+
return
|
248
|
+
end
|
249
|
+
json_response = @custom_instance_types_interface.update(instance_type['id'], payload)
|
250
|
+
|
251
|
+
if json_response['success']
|
252
|
+
if logo_file
|
253
|
+
begin
|
254
|
+
@custom_instance_types_interface.update_logo(json_response['instanceType']['id'], logo_file)
|
255
|
+
rescue RestClient::Exception => e
|
256
|
+
print_red_alert "Failed to save logo!"
|
257
|
+
print_rest_exception(e, options)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
if options[:json]
|
263
|
+
print JSON.pretty_generate(json_response), "\n"
|
264
|
+
return
|
265
|
+
end
|
266
|
+
|
267
|
+
print_green_success "Updated Instance Type #{instance_type_payload['name']}"
|
268
|
+
#list([])
|
269
|
+
rescue RestClient::Exception => e
|
270
|
+
print_rest_exception(e, options)
|
271
|
+
exit 1
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
def remove(args)
|
276
|
+
options = {}
|
277
|
+
optparse = OptionParser.new do|opts|
|
278
|
+
opts.banner = subcommand_usage("[name]")
|
279
|
+
build_common_options(opts, options, [:auto_confirm, :json, :dry_run])
|
280
|
+
end
|
281
|
+
optparse.parse!(args)
|
282
|
+
if args.count < 1
|
283
|
+
puts optparse
|
284
|
+
exit 1
|
285
|
+
end
|
286
|
+
connect(options)
|
287
|
+
|
288
|
+
begin
|
289
|
+
instance_type = find_custom_instance_type_by_name_or_code(args[0])
|
290
|
+
exit 1 if instance_type.nil?
|
291
|
+
|
292
|
+
unless Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the instance type #{instance_type['name']}?", options)
|
293
|
+
exit
|
294
|
+
end
|
295
|
+
if options[:dry_run]
|
296
|
+
print_dry_run @custom_instance_types_interface.dry.destroy(instance_type['id'])
|
297
|
+
return
|
298
|
+
end
|
299
|
+
json_response = @custom_instance_types_interface.destroy(instance_type['id'])
|
300
|
+
|
301
|
+
if options[:json]
|
302
|
+
print JSON.pretty_generate(json_response), "\n"
|
303
|
+
return
|
304
|
+
end
|
305
|
+
|
306
|
+
print_green_success "Removed Instance Type #{instance_type['name']}"
|
307
|
+
#list([])
|
308
|
+
rescue RestClient::Exception => e
|
309
|
+
print_rest_exception(e, options)
|
310
|
+
exit 1
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
def add_version(args)
|
315
|
+
options = {}
|
316
|
+
optparse = OptionParser.new do|opts|
|
317
|
+
opts.banner = subcommand_usage("[name]")
|
318
|
+
build_common_options(opts, options, [:options, :json])
|
319
|
+
end
|
320
|
+
optparse.parse!(args)
|
321
|
+
if args.count < 1
|
322
|
+
puts optparse
|
323
|
+
exit 1
|
324
|
+
end
|
325
|
+
connect(options)
|
326
|
+
begin
|
327
|
+
instance_type = find_custom_instance_type_by_name_or_code(args[0])
|
328
|
+
exit 1 if instance_type.nil?
|
329
|
+
|
330
|
+
#params = Morpheus::Cli::OptionTypes.prompt(add_version_option_types, options[:options], @api_client, options[:params])
|
331
|
+
provision_types = @provision_types_interface.get({customSupported: true})['provisionTypes']
|
332
|
+
if provision_types.empty?
|
333
|
+
print_red_alert "No available provision types found!"
|
334
|
+
exit 1
|
335
|
+
end
|
336
|
+
provision_type_options = provision_types.collect {|it| { 'name' => it['name'], 'value' => it['code']} }
|
337
|
+
payload = {'containerType' => {}, 'instanceTypeLayout' => {}, 'instanceType' => {}}
|
338
|
+
|
339
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => 'instanceTypeLayout', 'fieldName' => 'name', 'type' => 'text', 'fieldLabel' => 'Name', 'required' => true, 'description' => 'A name for this layout.'}], options[:options])
|
340
|
+
payload['instanceTypeLayout']['name'] = v_prompt['instanceTypeLayout']['name']
|
341
|
+
|
342
|
+
# shortName is only available for the first new version
|
343
|
+
if !instance_type['versions'] || instance_type['versions'].size == 0
|
344
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => 'containerType', 'fieldName' => 'shortName', 'type' => 'text', 'fieldLabel' => 'Short Name', 'required' => true, 'description' => 'The short name is a lowercase name with no spaces used for display in your container list.'}], options[:options])
|
345
|
+
payload['containerType']['shortName'] = v_prompt['containerType']['shortName']
|
346
|
+
end
|
347
|
+
|
348
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => 'containerType', 'fieldName' => 'provisionTypeCode', 'type' => 'select', 'selectOptions' => provision_type_options, 'fieldLabel' => 'Technology', 'required' => true, 'description' => 'The type of container technology.'}], options[:options])
|
349
|
+
payload['containerType']['provisionTypeCode'] = v_prompt['containerType']['provisionTypeCode']
|
350
|
+
provision_type = provision_types.find {|it| it['code'] == payload['containerType']['provisionTypeCode'] }
|
351
|
+
|
352
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => 'instanceTypeLayout', 'fieldName' => 'instanceVersion', 'type' => 'text', 'fieldLabel' => 'Version', 'required' => true, 'description' => 'A Version Number eg. 0.0.1'}], options[:options])
|
353
|
+
payload['instanceTypeLayout']['instanceVersion'] = v_prompt['instanceTypeLayout']['instanceVersion']
|
354
|
+
|
355
|
+
custom_option_types = provision_type['customOptionTypes']
|
356
|
+
|
357
|
+
if (!custom_option_types || custom_option_types.empty?)
|
358
|
+
puts yellow,"Sorry, no options were found for #{provision_type['name']}.",reset
|
359
|
+
exit 1
|
360
|
+
end
|
361
|
+
# prompt custom options for the selected provision type
|
362
|
+
field_group_name = custom_option_types.first['fieldGroup'] || "#{provision_type['name']} Options"
|
363
|
+
puts field_group_name
|
364
|
+
puts "==============="
|
365
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt(custom_option_types,options[:options],@api_client, {provisionTypCode: payload['provisionTypeCode']})
|
366
|
+
|
367
|
+
if v_prompt['containerType']
|
368
|
+
payload['containerType'].merge!(v_prompt['containerType'])
|
369
|
+
end
|
370
|
+
if v_prompt['containerType.config']
|
371
|
+
payload['containerType']['config'] = v_prompt['containerType.config']
|
372
|
+
end
|
373
|
+
if v_prompt['instanceTypeLayout']
|
374
|
+
payload['instanceTypeLayout'].merge!(v_prompt['instanceTypeLayout'])
|
375
|
+
end
|
376
|
+
# instanceType.backupType, which is not even persisted on the server?
|
377
|
+
if v_prompt['instanceType']
|
378
|
+
payload['instanceType'].merge!(v_prompt['instanceType'])
|
379
|
+
end
|
380
|
+
|
381
|
+
# puts "PAYLOAD:"
|
382
|
+
# puts JSON.pretty_generate(payload)
|
383
|
+
# puts "\nexiting early"
|
384
|
+
# exit 0
|
385
|
+
|
386
|
+
payload['exposedPorts'] = prompt_exposed_ports(options, @api_client)
|
387
|
+
|
388
|
+
request_payload = payload
|
389
|
+
json_response = @custom_instance_types_interface.create_version(instance_type['id'], request_payload)
|
390
|
+
|
391
|
+
if options[:json]
|
392
|
+
print JSON.pretty_generate(json_response), "\n"
|
393
|
+
return
|
394
|
+
end
|
395
|
+
|
396
|
+
print_green_success "Added Instance Type Version #{instance_type['name']} - #{payload['instanceTypeLayout']['instanceVersion']}"
|
397
|
+
#list([])
|
398
|
+
rescue RestClient::Exception => e
|
399
|
+
print_rest_exception(e, options)
|
400
|
+
exit 1
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
|
405
|
+
private
|
406
|
+
|
407
|
+
def find_custom_instance_type_by_code(code)
|
408
|
+
instance_type_results = @custom_instance_types_interface.list({code: code})
|
409
|
+
if instance_type_results['instanceTypes'].empty?
|
410
|
+
print_red_alert "Custom Instance Type not found by code #{code}"
|
411
|
+
return nil
|
412
|
+
end
|
413
|
+
return instance_type_results['instanceTypes'][0]
|
414
|
+
end
|
415
|
+
|
416
|
+
def find_custom_instance_type_by_name(name)
|
417
|
+
instance_type_results = @custom_instance_types_interface.list({name: name})
|
418
|
+
instance_types = instance_type_results['instanceTypes']
|
419
|
+
if instance_types.empty?
|
420
|
+
print_red_alert "Custom Instance Type not found by name #{name}"
|
421
|
+
return nil
|
422
|
+
elsif instance_types.size > 1
|
420
423
|
print_red_alert "Found #{instance_types.size} instance types by name #{name}"
|
421
424
|
print red, "\n"
|
422
425
|
instance_types.each do |instance_type|
|
423
426
|
print "= #{instance_type['name']} (#{instance_type['code']})\n"
|
424
427
|
end
|
425
428
|
print "\n", "Find by code:<code> instead"
|
426
|
-
print reset,"\n
|
429
|
+
print reset,"\n"
|
427
430
|
return nil
|
428
431
|
else
|
429
432
|
return instance_types[0]
|
430
433
|
end
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
434
|
+
end
|
435
|
+
|
436
|
+
def find_custom_instance_type_by_name_or_code(val)
|
437
|
+
if val =~ /code:/
|
438
|
+
find_custom_instance_type_by_code(val.sub('code:', ''))
|
439
|
+
else
|
440
|
+
find_custom_instance_type_by_name(val)
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
444
|
+
def instance_type_categories
|
445
|
+
[
|
446
|
+
{'name' => 'Web', 'value' => 'web'},
|
447
|
+
{'name' => 'SQL', 'value' => 'sql'},
|
448
|
+
{'name' => 'NoSQL', 'value' => 'nosql'},
|
449
|
+
{'name' => 'Apps', 'value' => 'apps'},
|
450
|
+
{'name' => 'Network', 'value' => 'network'},
|
451
|
+
{'name' => 'Messaging', 'value' => 'messaging'},
|
452
|
+
{'name' => 'Cache', 'value' => 'cache'},
|
453
|
+
{'name' => 'OS', 'value' => 'os'},
|
454
|
+
{'name' => 'Cloud', 'value' => 'cloud'},
|
455
|
+
{'name' => 'Utility', 'value' => 'utility'}
|
456
|
+
]
|
457
|
+
end
|
458
|
+
|
459
|
+
def add_instance_type_option_types
|
460
|
+
[
|
461
|
+
{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
|
462
|
+
{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'displayOrder' => 2},
|
463
|
+
{'fieldName' => 'category', 'fieldLabel' => 'Category', 'type' => 'select', 'selectOptions' => instance_type_categories, 'required' => true, 'displayOrder' => 3},
|
464
|
+
{'fieldName' => 'logo', 'fieldLabel' => 'Icon File', 'type' => 'text', 'displayOrder' => 4},
|
465
|
+
{'fieldName' => 'visibility', 'fieldLabel' => 'Visibility', 'type' => 'select', 'selectOptions' => [{'name' => 'Private', 'value' => 'private'}, {'name' => 'Public', 'value' => 'public'}], 'defaultValue' => 'private', 'displayOrder' => 5},
|
466
|
+
{'fieldName' => 'environmentPrefix', 'fieldLabel' => 'Environment Prefix', 'type' => 'text', 'displayOrder' => 6, 'description' => 'Used for exportable environment variables when tying instance types together in app contexts. If not specified a name will be generated.'},
|
467
|
+
{'fieldName' => 'hasAutoScale', 'fieldLabel' => 'Enable Scaling (Horizontal)', 'type' => 'checkbox', 'displayOrder' => 7},
|
468
|
+
{'fieldName' => 'hasDeployment', 'fieldLabel' => 'Supports Deployments', 'type' => 'checkbox', 'displayOrder' => 8, 'description' => 'Requires a data volume be configured on each version. Files will be copied into this location.'}
|
469
|
+
]
|
470
|
+
end
|
471
|
+
|
472
|
+
def update_instance_type_option_types(instance_type=nil)
|
473
|
+
if instance_type
|
474
|
+
opts = add_instance_type_option_types
|
475
|
+
opts.find {|opt| opt['fieldName'] == 'name'}['defaultValue'] = instance_type['name']
|
476
|
+
opts
|
477
|
+
else
|
478
|
+
add_instance_type_option_types
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
def add_version_option_types
|
483
|
+
[
|
484
|
+
{'fieldName' => 'versionNumber', 'fieldLabel' => 'Version Number', 'type' => 'text', 'required' => true, 'displayOrder' => 1}
|
485
|
+
]
|
486
|
+
end
|
487
|
+
|
488
|
+
def update_version_option_types
|
489
|
+
add_version_option_types
|
490
|
+
end
|
491
|
+
|
492
|
+
def load_balance_protocols
|
493
|
+
[
|
494
|
+
{'name' => 'None', 'value' => ''},
|
495
|
+
{'name' => 'HTTP', 'value' => 'HTTP'},
|
496
|
+
{'name' => 'HTTPS', 'value' => 'HTTPS'},
|
497
|
+
{'name' => 'TCP', 'value' => 'TCP'}
|
498
|
+
]
|
499
|
+
end
|
500
|
+
|
501
|
+
# Prompts user for exposed ports array
|
499
502
|
# returns array of port objects
|
500
503
|
def prompt_exposed_ports(options={}, api_client=nil, api_params={})
|
501
504
|
#puts "Configure ports:"
|
@@ -503,37 +506,33 @@ private
|
|
503
506
|
|
504
507
|
ports = []
|
505
508
|
port_index = 0
|
506
|
-
|
507
509
|
has_another_port = options[:options] && options[:options]["exposedPort#{port_index}"]
|
508
510
|
add_another_port = has_another_port || (!no_prompt && Morpheus::Cli::OptionTypes.confirm("Add an exposed port?"))
|
509
|
-
|
510
511
|
while add_another_port do
|
511
|
-
|
512
|
-
field_context = "exposedPort#{port_index}"
|
512
|
+
field_context = "exposedPort#{port_index}"
|
513
513
|
|
514
|
-
|
515
|
-
|
514
|
+
port = {}
|
515
|
+
#port['name'] ||= "Port #{port_index}"
|
516
|
+
port_label = port_index == 0 ? "Port" : "Port [#{port_index+1}]"
|
517
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'name', 'type' => 'text', 'fieldLabel' => "#{port_label} Name", 'required' => false, 'description' => 'Choose a name for this port.', 'defaultValue' => port['name']}], options[:options])
|
518
|
+
port['name'] = v_prompt[field_context]['name']
|
516
519
|
|
517
|
-
|
518
|
-
|
520
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'port', 'type' => 'number', 'fieldLabel' => "#{port_label} Number", 'required' => true, 'description' => 'A port number. eg. 8001', 'defaultValue' => (port['port'] ? port['port'].to_i : nil)}], options[:options])
|
521
|
+
port['port'] = v_prompt[field_context]['port']
|
519
522
|
|
520
|
-
|
521
|
-
|
523
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldContext' => field_context, 'fieldName' => 'loadBalanceProtocol', 'type' => 'select', 'fieldLabel' => "#{port_label} LB", 'selectOptions' => load_balance_protocols, 'required' => false, 'skipSingleOption' => true, 'description' => 'Choose a load balance protocol.', 'defaultValue' => port['loadBalanceProtocol']}], options[:options])
|
524
|
+
port['loadBalanceProtocol'] = v_prompt[field_context]['loadBalanceProtocol']
|
522
525
|
|
523
|
-
|
524
|
-
|
526
|
+
ports << port
|
527
|
+
port_index += 1
|
528
|
+
has_another_port = options[:options] && options[:options]["exposedPort#{port_index}"]
|
529
|
+
add_another_port = has_another_port || (!no_prompt && Morpheus::Cli::OptionTypes.confirm("Add another exposed port?"))
|
530
|
+
|
531
|
+
end
|
525
532
|
|
526
|
-
ports << port
|
527
|
-
|
528
|
-
port_index += 1
|
529
|
-
has_another_port = options[:options] && options[:options]["exposedPort#{port_index}"]
|
530
|
-
add_another_port = has_another_port || (!no_prompt && Morpheus::Cli::OptionTypes.confirm("Add another exposed port?"))
|
531
533
|
|
534
|
+
return ports
|
532
535
|
end
|
533
536
|
|
534
537
|
|
535
|
-
return ports
|
536
538
|
end
|
537
|
-
|
538
|
-
|
539
|
-
end
|