morpheus-cli 4.1.13 → 4.1.14
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/lib/morpheus/cli/cli_command.rb +5 -1
- data/lib/morpheus/cli/hosts.rb +5 -5
- data/lib/morpheus/cli/library_instance_types_command.rb +18 -0
- data/lib/morpheus/cli/library_layouts_command.rb +84 -15
- data/lib/morpheus/cli/library_spec_templates_command.rb +50 -134
- data/lib/morpheus/cli/mixins/library_helper.rb +169 -0
- data/lib/morpheus/cli/mixins/print_helper.rb +28 -5
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/logging.rb +2 -0
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ed9f7ed5543846a64411f1e25133cad8df66ee4a2db836754f4733225d83962
|
4
|
+
data.tar.gz: 859c8b97f7ca569359cb795462803da90c0ed624998c67cf358aa5b5ae8a7df5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c140d5c006c3bb4b179c8d763514b47cc8b36f8526cb60472f39043601054e5da55cadd79039ec02cf756e54fe36ae3358a5fb1029ca18a0eef9ed60eb5a1e51
|
7
|
+
data.tar.gz: f81e24cbe8a4a62c46d33420baa43e9a599930ac2cc1066f05fac766fb82d0d96511dd2a06a99cd5b1b5f55edf56dc6a19a59004f7e997388d64ddf85b533b0d
|
@@ -567,13 +567,17 @@ module Morpheus
|
|
567
567
|
end
|
568
568
|
|
569
569
|
when :fields
|
570
|
-
opts.on('-
|
570
|
+
opts.on('-f', '--fields x,y,z', Array, "Filter Output to a limited set of fields. Default is all fields.") do |val|
|
571
|
+
options[:include_fields] = val
|
572
|
+
end
|
573
|
+
opts.on('-F', '--old-fields x,y,z', Array, "alias for -f, --fields") do |val|
|
571
574
|
options[:include_fields] = val
|
572
575
|
end
|
573
576
|
opts.on(nil, '--all-fields', "Show all fields. Useful for showing hidden columns on wide tables.") do
|
574
577
|
options[:all_fields] = true
|
575
578
|
end
|
576
579
|
opts.add_hidden_option('--all-fields') if opts.is_a?(Morpheus::Cli::OptionParser)
|
580
|
+
opts.add_hidden_option('-F,') if opts.is_a?(Morpheus::Cli::OptionParser)
|
577
581
|
|
578
582
|
when :thin
|
579
583
|
opts.on( '--thin', '--thin', "Format headers and columns with thin borders." ) do |val|
|
data/lib/morpheus/cli/hosts.rb
CHANGED
@@ -109,10 +109,10 @@ class Morpheus::Cli::Hosts
|
|
109
109
|
options[:details] = true
|
110
110
|
end
|
111
111
|
opts.on('--tag-compliant', "Displays only servers that are valid according to applied tag policies. Does not show servers that do not have tag policies." ) do
|
112
|
-
|
112
|
+
params[:tagCompliant] = true
|
113
113
|
end
|
114
114
|
opts.on('--non-tag-compliant', "Displays only servers with tag compliance warnings." ) do
|
115
|
-
|
115
|
+
params[:tagCompliant] = false
|
116
116
|
end
|
117
117
|
build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
|
118
118
|
opts.footer = "List hosts."
|
@@ -1238,8 +1238,8 @@ class Morpheus::Cli::Hosts
|
|
1238
1238
|
end
|
1239
1239
|
@servers_interface.setopts(options)
|
1240
1240
|
if options[:dry_run]
|
1241
|
-
print_dry_run
|
1242
|
-
return
|
1241
|
+
print_dry_run(@servers_interface.dry.make_managed(host['id'], payload), options)
|
1242
|
+
return 0
|
1243
1243
|
end
|
1244
1244
|
json_response = @servers_interface.make_managed(host['id'], payload)
|
1245
1245
|
if options[:json]
|
@@ -1249,7 +1249,7 @@ class Morpheus::Cli::Hosts
|
|
1249
1249
|
print_green_success "Host #{host['name']} is being converted to managed."
|
1250
1250
|
puts "Public Key:\n#{json_response['publicKey']}\n(copy to your authorized_keys file)"
|
1251
1251
|
end
|
1252
|
-
return
|
1252
|
+
return 0
|
1253
1253
|
rescue RestClient::Exception => e
|
1254
1254
|
print_rest_exception(e, options)
|
1255
1255
|
exit 1
|
@@ -251,12 +251,25 @@ class Morpheus::Cli::LibraryInstanceTypesCommand
|
|
251
251
|
opts.footer = "Create a new instance type."
|
252
252
|
end
|
253
253
|
optparse.parse!(args)
|
254
|
+
if args.count > 1
|
255
|
+
raise_command_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args}\n#{optparse}"
|
256
|
+
end
|
257
|
+
if args[0]
|
258
|
+
#params["name"] = args[0]
|
259
|
+
options[:options]["name"] = args[0]
|
260
|
+
end
|
254
261
|
connect(options)
|
255
262
|
begin
|
263
|
+
passed_options = (options[:options] || {}).reject {|k,v| k.is_a?(Symbol) }
|
256
264
|
payload = nil
|
257
265
|
if options[:payload]
|
258
266
|
payload = options[:payload]
|
267
|
+
# merge -O options
|
268
|
+
payload.deep_merge!({'instanceType' => passed_options}) unless passed_options.empty?
|
259
269
|
else
|
270
|
+
# merge -O options
|
271
|
+
params.deep_merge!(passed_options) unless passed_options.empty?
|
272
|
+
# prompt
|
260
273
|
v_prompt = Morpheus::Cli::OptionTypes.prompt(add_instance_type_option_types, options[:options], @api_client, options[:params])
|
261
274
|
params.deep_merge!(v_prompt)
|
262
275
|
if params['logo']
|
@@ -328,10 +341,15 @@ class Morpheus::Cli::LibraryInstanceTypesCommand
|
|
328
341
|
begin
|
329
342
|
instance_type = find_instance_type_by_name_or_id(args[0])
|
330
343
|
exit 1 if instance_type.nil?
|
344
|
+
passed_options = (options[:options] || {}).reject {|k,v| k.is_a?(Symbol) }
|
331
345
|
payload = nil
|
332
346
|
if options[:payload]
|
333
347
|
payload = options[:payload]
|
348
|
+
# merge -O options
|
349
|
+
payload.deep_merge!({'instanceType' => passed_options}) unless passed_options.empty?
|
334
350
|
else
|
351
|
+
# merge -O options
|
352
|
+
params.deep_merge!(passed_options) unless passed_options.empty?
|
335
353
|
# option_types = update_instance_type_option_types(instance_type)
|
336
354
|
# params = Morpheus::Cli::OptionTypes.prompt(option_types, options[:options], @api_client, options[:params])
|
337
355
|
params.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
@@ -20,6 +20,8 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
20
20
|
@api_client = establish_remote_appliance_connection(opts)
|
21
21
|
@library_layouts_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).library_layouts
|
22
22
|
@library_instance_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).library_instance_types
|
23
|
+
@spec_templates_interface = @api_client.library_spec_templates
|
24
|
+
@spec_template_types_interface = @api_client.library_spec_template_types
|
23
25
|
@provision_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).provision_types
|
24
26
|
@option_types_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).option_types
|
25
27
|
@option_type_lists_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).option_type_lists
|
@@ -156,6 +158,7 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
156
158
|
description_cols = {
|
157
159
|
"ID" => lambda {|it| it['id'] },
|
158
160
|
"Name" => lambda {|it| it['name'] },
|
161
|
+
"Instance Type" => lambda {|it| it['instanceType']['name'] rescue '' },
|
159
162
|
#"Code" => lambda {|it| it['code'] },
|
160
163
|
"Version" => lambda {|it| it['instanceVersion'] },
|
161
164
|
"Description" => lambda {|it| it['description'] },
|
@@ -223,9 +226,9 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
223
226
|
# print yellow,"No option types found for this layout.","\n",reset
|
224
227
|
end
|
225
228
|
|
226
|
-
print_h2 "Node Types"
|
227
229
|
layout_node_types = layout['containerTypes']
|
228
230
|
if layout_node_types && layout_node_types.size > 0
|
231
|
+
print_h2 "Node Types"
|
229
232
|
# match UI sorting [version desc, name asc]
|
230
233
|
# or use something simpler like one of these
|
231
234
|
layout_node_types = layout_node_types.sort { |a,b| a['name'] <=> b['name'] }
|
@@ -240,7 +243,21 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
240
243
|
]
|
241
244
|
print as_pretty_table(layout_node_types, node_type_columns)
|
242
245
|
else
|
243
|
-
print yellow,"No node types for this layout.","\n",reset
|
246
|
+
# print yellow,"No node types for this layout.","\n",reset
|
247
|
+
end
|
248
|
+
|
249
|
+
layout_spec_templates = layout['specTemplates']
|
250
|
+
if layout_spec_templates && layout_spec_templates.size > 0
|
251
|
+
print_h2 "Spec Templates"
|
252
|
+
layout_spec_templates = layout_spec_templates.sort { |a,b| a['name'] <=> b['name'] }
|
253
|
+
spec_template_columns = [
|
254
|
+
{"ID" => lambda {|it| it['id'] } },
|
255
|
+
{"NAME" => lambda {|it| it['name'] } },
|
256
|
+
{"TYPE" => lambda {|it| it['type']['name'] rescue '' } }
|
257
|
+
]
|
258
|
+
print as_pretty_table(layout_spec_templates, spec_template_columns)
|
259
|
+
else
|
260
|
+
# print yellow,"No spec templates for this layout.","\n",reset
|
244
261
|
end
|
245
262
|
|
246
263
|
print reset,"\n"
|
@@ -281,11 +298,26 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
281
298
|
opts.on('--workflow ID', String, "Workflow") do |val|
|
282
299
|
params['taskSetId'] = val.to_i
|
283
300
|
end
|
284
|
-
opts.on('--option-types x,y,z', Array, "List of Option Type IDs") do |
|
285
|
-
|
301
|
+
opts.on('--option-types [x,y,z]', Array, "List of Option Type IDs") do |list|
|
302
|
+
if list.nil?
|
303
|
+
option_type_ids = []
|
304
|
+
else
|
305
|
+
option_type_ids = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
306
|
+
end
|
307
|
+
end
|
308
|
+
opts.on('--node-types [x,y,z]', Array, "List of Node Type IDs") do |list|
|
309
|
+
if list.nil?
|
310
|
+
node_type_ids = []
|
311
|
+
else
|
312
|
+
node_type_ids = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
313
|
+
end
|
286
314
|
end
|
287
|
-
opts.on('--
|
288
|
-
|
315
|
+
opts.on('--spec-templates [x,y,z]', Array, "List of Spec Templates to include in this layout, comma separated list of names or IDs.") do |list|
|
316
|
+
if list.nil?
|
317
|
+
params['specTemplates'] = []
|
318
|
+
else
|
319
|
+
params['specTemplates'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
320
|
+
end
|
289
321
|
end
|
290
322
|
#build_option_type_options(opts, options, add_layout_option_types())
|
291
323
|
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
@@ -293,17 +325,21 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
293
325
|
"[instance-type] is required and can be passed as --instance-type instead."
|
294
326
|
end
|
295
327
|
optparse.parse!(args)
|
296
|
-
|
297
|
-
|
328
|
+
if args.count > 1
|
329
|
+
raise_command_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args}\n#{optparse}"
|
330
|
+
end
|
331
|
+
if args[0]
|
332
|
+
#params["name"] = args[0]
|
333
|
+
instance_type_id = args[0]
|
334
|
+
end
|
298
335
|
if instance_type_id.nil?
|
299
336
|
instance_type_id = args[0]
|
300
337
|
end
|
301
|
-
|
302
338
|
if !instance_type_id
|
303
339
|
puts optparse
|
304
|
-
|
340
|
+
return 1
|
305
341
|
end
|
306
|
-
|
342
|
+
connect(options)
|
307
343
|
begin
|
308
344
|
instance_type = find_instance_type_by_name_or_id(instance_type_id)
|
309
345
|
exit 1 if instance_type.nil?
|
@@ -377,6 +413,14 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
377
413
|
# prompt
|
378
414
|
end
|
379
415
|
|
416
|
+
# SPEC TEMPLATES
|
417
|
+
prompt_results = prompt_for_spec_templates(params, options, @api_client)
|
418
|
+
if prompt_results[:success]
|
419
|
+
params['specTemplates'] = prompt_results[:data] unless prompt_results[:data].nil?
|
420
|
+
else
|
421
|
+
return 1
|
422
|
+
end
|
423
|
+
|
380
424
|
|
381
425
|
payload = {'instanceTypeLayout' => params}
|
382
426
|
|
@@ -431,11 +475,26 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
431
475
|
opts.on('--workflow ID', String, "Workflow") do |val|
|
432
476
|
params['taskSetId'] = val.to_i
|
433
477
|
end
|
434
|
-
opts.on('--option-types x,y,z', Array, "List of Option Type IDs") do |
|
435
|
-
|
478
|
+
opts.on('--option-types [x,y,z]', Array, "List of Option Type IDs") do |list|
|
479
|
+
if list.nil?
|
480
|
+
option_type_ids = []
|
481
|
+
else
|
482
|
+
option_type_ids = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
483
|
+
end
|
484
|
+
end
|
485
|
+
opts.on('--node-types [x,y,z]', Array, "List of Node Type IDs") do |list|
|
486
|
+
if list.nil?
|
487
|
+
node_type_ids = []
|
488
|
+
else
|
489
|
+
node_type_ids = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
490
|
+
end
|
436
491
|
end
|
437
|
-
opts.on('--
|
438
|
-
|
492
|
+
opts.on('--spec-templates [x,y,z]', Array, "List of Spec Templates to include in this layout, comma separated list of names or IDs.") do |list|
|
493
|
+
if list.nil?
|
494
|
+
params['specTemplates'] = []
|
495
|
+
else
|
496
|
+
params['specTemplates'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
497
|
+
end
|
439
498
|
end
|
440
499
|
#build_option_type_options(opts, options, update_layout_option_types())
|
441
500
|
build_common_options(opts, options, [:options, :json, :dry_run, :remote])
|
@@ -479,6 +538,16 @@ class Morpheus::Cli::LibraryLayoutsCommand
|
|
479
538
|
# prompt
|
480
539
|
end
|
481
540
|
|
541
|
+
# SPEC TEMPLATES
|
542
|
+
if params['specTemplates']
|
543
|
+
prompt_results = prompt_for_spec_templates(params, options, @api_client)
|
544
|
+
if prompt_results[:success]
|
545
|
+
params['specTemplates'] = prompt_results[:data] unless prompt_results[:data].nil?
|
546
|
+
else
|
547
|
+
return 1
|
548
|
+
end
|
549
|
+
end
|
550
|
+
|
482
551
|
if params.empty?
|
483
552
|
puts optparse
|
484
553
|
exit 1
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'morpheus/cli/cli_command'
|
2
|
+
require 'morpheus/cli/mixins/library_helper'
|
2
3
|
|
3
4
|
class Morpheus::Cli::LibrarySpecTemplatesCommand
|
4
5
|
include Morpheus::Cli::CliCommand
|
6
|
+
include Morpheus::Cli::LibraryHelper
|
5
7
|
set_command_name :'library-spec-templates'
|
6
|
-
set_command_hidden
|
7
8
|
register_subcommands :list, :get, :add, :update, :remove, :list_types
|
8
9
|
|
9
10
|
def connect(opts)
|
@@ -73,6 +74,9 @@ class Morpheus::Cli::LibrarySpecTemplatesCommand
|
|
73
74
|
options = {}
|
74
75
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
75
76
|
opts.banner = subcommand_usage("[name]")
|
77
|
+
opts.on('--no-content', "Do not display content." ) do
|
78
|
+
options[:no_content] = true
|
79
|
+
end
|
76
80
|
build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
|
77
81
|
end
|
78
82
|
optparse.parse!(args)
|
@@ -90,7 +94,7 @@ class Morpheus::Cli::LibrarySpecTemplatesCommand
|
|
90
94
|
def _get(id, options)
|
91
95
|
|
92
96
|
begin
|
93
|
-
resource_spec =
|
97
|
+
resource_spec = find_spec_template_by_name_or_id(id)
|
94
98
|
if resource_spec.nil?
|
95
99
|
return 1
|
96
100
|
end
|
@@ -129,27 +133,38 @@ class Morpheus::Cli::LibrarySpecTemplatesCommand
|
|
129
133
|
# "Created" => lambda {|it| format_local_dt(it['dateCreated']) + " by #{it['createdBy']}" },
|
130
134
|
# "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) + " by #{it['updatedBy'] || it['createdBy']}" },
|
131
135
|
}
|
136
|
+
template_type = resource_spec['type']['code'] rescue nil
|
137
|
+
if template_type.to_s.downcase == 'cloudformation'
|
138
|
+
cloudformation_description_cols = {
|
139
|
+
"CAPABILITY_IAM" => lambda {|it| format_boolean(it['config']['cloudformation']['IAM']) rescue '' },
|
140
|
+
"CAPABILITY_NAMED_IAM" => lambda {|it| format_boolean(it['config']['cloudformation']['CAPABILITY_NAMED_IAM']) rescue '' },
|
141
|
+
"CAPABILITY_AUTO_EXPAND" => lambda {|it| format_boolean(it['config']['cloudformation']['CAPABILITY_AUTO_EXPAND']) rescue '' },
|
142
|
+
}
|
143
|
+
description_cols.merge!(cloudformation_description_cols)
|
144
|
+
end
|
132
145
|
print_description_list(description_cols, resource_spec)
|
133
146
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
if file_content
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
147
|
+
unless options[:no_content]
|
148
|
+
file_content = resource_spec['file']
|
149
|
+
print_h2 "Content"
|
150
|
+
if file_content
|
151
|
+
if file_content['sourceType'] == 'local'
|
152
|
+
puts file_content['content']
|
153
|
+
elsif file_content['sourceType'] == 'url'
|
154
|
+
puts "URL: #{file_content['contentPath']}"
|
155
|
+
elsif file_content['sourceType'] == 'repository'
|
156
|
+
puts "Repository: #{file_content['repository']['name'] rescue 'n/a'}"
|
157
|
+
puts "Path: #{file_content['contentPath']}"
|
158
|
+
if file_content['contentRef']
|
159
|
+
puts "Ref: #{file_content['contentRef']}"
|
160
|
+
end
|
161
|
+
else
|
162
|
+
puts "Source: #{file_content['sourceType']}"
|
163
|
+
puts "Path: #{file_content['contentPath']}"
|
146
164
|
end
|
147
165
|
else
|
148
|
-
|
149
|
-
puts "Path: #{file_content['contentPath']}"
|
166
|
+
print yellow,"No file content.",reset,"\n"
|
150
167
|
end
|
151
|
-
else
|
152
|
-
print yellow,"No file content.",reset,"\n"
|
153
168
|
end
|
154
169
|
|
155
170
|
print reset,"\n"
|
@@ -171,7 +186,7 @@ class Morpheus::Cli::LibrarySpecTemplatesCommand
|
|
171
186
|
opts.on('--name VALUE', String, "Name") do |val|
|
172
187
|
params['name'] = val
|
173
188
|
end
|
174
|
-
opts.on('--type
|
189
|
+
opts.on('-t', '--type TYPE', "Spec Template Type. kubernetes, helm, terraform, cloudFormation") do |val|
|
175
190
|
template_type = val.to_s
|
176
191
|
end
|
177
192
|
opts.on('--source VALUE', String, "Source Type. local, repository, url") do |val|
|
@@ -219,8 +234,14 @@ class Morpheus::Cli::LibrarySpecTemplatesCommand
|
|
219
234
|
begin
|
220
235
|
# construct payload
|
221
236
|
payload = nil
|
237
|
+
passed_options = options[:options].reject {|k,v| k.is_a?(Symbol) }
|
222
238
|
if options[:payload]
|
223
239
|
payload = options[:payload]
|
240
|
+
# merge -O options into normally parsed options
|
241
|
+
params['file'] = file_params unless file_params.empty?
|
242
|
+
unless params.empty?
|
243
|
+
payload.deep_merge!({'specTemplate' => params })
|
244
|
+
end
|
224
245
|
else
|
225
246
|
# merge -O options into normally parsed options
|
226
247
|
params.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
|
@@ -229,7 +250,7 @@ class Morpheus::Cli::LibrarySpecTemplatesCommand
|
|
229
250
|
params['name'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true}], options[:options], @api_client,{})['name']
|
230
251
|
end
|
231
252
|
if template_type.nil?
|
232
|
-
#
|
253
|
+
# use code instead of id
|
233
254
|
#template_type = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'fieldLabel' => 'Type', 'type' => 'select', 'optionSource' => 'resourceSpecType', 'required' => true}], options[:options], @api_client,{})['type']
|
234
255
|
#params['type'] = {'id' => template_type}
|
235
256
|
spec_type_dropdown = get_all_spec_template_types.collect { |it| {'value' => it['code'], 'name' => it['name']} }
|
@@ -242,10 +263,12 @@ class Morpheus::Cli::LibrarySpecTemplatesCommand
|
|
242
263
|
template_type = template_type_obj['code']
|
243
264
|
params['type'] = {'code' => template_type}
|
244
265
|
end
|
266
|
+
# source
|
245
267
|
if source_type.nil?
|
246
268
|
source_type = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'source', 'fieldLabel' => 'Source', 'type' => 'select', 'optionSource' => 'fileContentSource', 'required' => true, 'defaultValue' => 'local'}], options[:options], @api_client,{})['source']
|
247
269
|
file_params['sourceType'] = source_type
|
248
270
|
end
|
271
|
+
# source type options
|
249
272
|
if source_type == "local"
|
250
273
|
# prompt for content
|
251
274
|
if file_params['content'].nil?
|
@@ -267,8 +290,9 @@ class Morpheus::Cli::LibrarySpecTemplatesCommand
|
|
267
290
|
file_params['contentRef'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'ref', 'fieldLabel' => 'Version Ref', 'type' => 'text'}], options[:options], @api_client,{})['ref']
|
268
291
|
end
|
269
292
|
end
|
270
|
-
|
271
|
-
|
293
|
+
# config
|
294
|
+
if template_type.to_s.downcase == "cloudformation"
|
295
|
+
# JD: the field names the UI uses are inconsistent, should fix in api...
|
272
296
|
cloud_formation_option_types = [
|
273
297
|
{'fieldContext' => 'config', 'fieldName' => 'cloudformation.IAM', 'fieldLabel' => 'CAPABILITY_IAM', 'type' => 'checkbox'},
|
274
298
|
{'fieldContext' => 'config', 'fieldName' => 'cloudformation.CAPABILITY_NAMED_IAM', 'fieldLabel' => 'CAPABILITY_NAMED_IAM', 'type' => 'checkbox'},
|
@@ -311,7 +335,7 @@ class Morpheus::Cli::LibrarySpecTemplatesCommand
|
|
311
335
|
opts.on('--name VALUE', String, "Name") do |val|
|
312
336
|
params['name'] = val
|
313
337
|
end
|
314
|
-
opts.on('--type
|
338
|
+
opts.on('-t', '--type TYPE', "Spec Template Type. kubernetes, helm, terraform, cloudFormation") do |val|
|
315
339
|
template_type = val.to_s
|
316
340
|
end
|
317
341
|
opts.on('--source VALUE', String, "Source Type. local, repository, url") do |val|
|
@@ -352,7 +376,7 @@ class Morpheus::Cli::LibrarySpecTemplatesCommand
|
|
352
376
|
end
|
353
377
|
connect(options)
|
354
378
|
begin
|
355
|
-
resource_spec =
|
379
|
+
resource_spec = find_spec_template_by_name_or_id(args[0])
|
356
380
|
if resource_spec.nil?
|
357
381
|
return 1
|
358
382
|
end
|
@@ -443,7 +467,7 @@ class Morpheus::Cli::LibrarySpecTemplatesCommand
|
|
443
467
|
connect(options)
|
444
468
|
|
445
469
|
begin
|
446
|
-
resource_spec =
|
470
|
+
resource_spec = find_spec_template_by_name_or_id(args[0])
|
447
471
|
if resource_spec.nil?
|
448
472
|
return 1
|
449
473
|
end
|
@@ -531,114 +555,6 @@ class Morpheus::Cli::LibrarySpecTemplatesCommand
|
|
531
555
|
|
532
556
|
private
|
533
557
|
|
534
|
-
|
535
|
-
if val.to_s =~ /\A\d{1,}\Z/
|
536
|
-
return find_resource_spec_by_id(val)
|
537
|
-
else
|
538
|
-
return find_resource_spec_by_name(val)
|
539
|
-
end
|
540
|
-
end
|
541
|
-
|
542
|
-
def find_resource_spec_by_id(id)
|
543
|
-
begin
|
544
|
-
json_response = @spec_templates_interface.get(id.to_i)
|
545
|
-
return json_response['specTemplate']
|
546
|
-
rescue RestClient::Exception => e
|
547
|
-
if e.response && e.response.code == 404
|
548
|
-
print_red_alert "Spec Template not found by id #{id}"
|
549
|
-
else
|
550
|
-
raise e
|
551
|
-
end
|
552
|
-
end
|
553
|
-
end
|
554
|
-
|
555
|
-
def find_resource_spec_by_name(name)
|
556
|
-
resource_specs = @spec_templates_interface.list({name: name.to_s})['specTemplates']
|
557
|
-
if resource_specs.empty?
|
558
|
-
print_red_alert "Spec Template not found by name #{name}"
|
559
|
-
return nil
|
560
|
-
elsif resource_specs.size > 1
|
561
|
-
print_red_alert "#{resource_specs.size} spec templates found by name #{name}"
|
562
|
-
print_resource_specs_table(resource_specs, {color: red})
|
563
|
-
print_red_alert "Try using ID instead"
|
564
|
-
print reset,"\n"
|
565
|
-
return nil
|
566
|
-
else
|
567
|
-
return resource_specs[0]
|
568
|
-
end
|
569
|
-
end
|
570
|
-
|
571
|
-
def print_resource_specs_table(resource_specs, opts={})
|
572
|
-
columns = [
|
573
|
-
{"ID" => lambda {|resource_spec| resource_spec['id'] } },
|
574
|
-
{"NAME" => lambda {|resource_spec| resource_spec['name'] } },
|
575
|
-
#{"OWNER" => lambda {|resource_spec| resource_spec['account'] ? resource_spec['account']['name'] : '' } },
|
576
|
-
]
|
577
|
-
if opts[:include_fields]
|
578
|
-
columns = opts[:include_fields]
|
579
|
-
end
|
580
|
-
print as_pretty_table(resource_specs, columns, opts)
|
581
|
-
end
|
582
|
-
|
583
|
-
def find_spec_template_type_by_id(id)
|
584
|
-
begin
|
585
|
-
json_response = @spec_template_types_interface.get(id.to_i)
|
586
|
-
return json_response['networkType']
|
587
|
-
rescue RestClient::Exception => e
|
588
|
-
if e.response && e.response.code == 404
|
589
|
-
print_red_alert "Network Type not found by id #{id}"
|
590
|
-
return nil
|
591
|
-
else
|
592
|
-
raise e
|
593
|
-
end
|
594
|
-
end
|
595
|
-
end
|
596
|
-
|
597
|
-
# def find_spec_template_type_by_name(name)
|
598
|
-
# json_response = @spec_template_types_interface.list({name: name.to_s})
|
599
|
-
# spec_template_types = json_response['networkTypes']
|
600
|
-
# if spec_template_types.empty?
|
601
|
-
# print_red_alert "Network Type not found by name #{name}"
|
602
|
-
# return spec_template_types
|
603
|
-
# elsif spec_template_types.size > 1
|
604
|
-
# print_red_alert "#{spec_template_types.size} network types found by name #{name}"
|
605
|
-
# rows = spec_template_types.collect do |it|
|
606
|
-
# {id: it['id'], name: it['name']}
|
607
|
-
# end
|
608
|
-
# puts as_pretty_table(rows, [:id, :name], {color:red})
|
609
|
-
# return nil
|
610
|
-
# else
|
611
|
-
# return spec_template_types[0]
|
612
|
-
# end
|
613
|
-
# end
|
614
|
-
|
615
|
-
def find_spec_template_type_by_name_or_code(name)
|
616
|
-
spec_template_types = get_all_spec_template_types().select { |it| name && it['code'] == name || it['name'] == name }
|
617
|
-
if spec_template_types.empty?
|
618
|
-
print_red_alert "Spec Template Type not found by code #{name}"
|
619
|
-
return nil
|
620
|
-
elsif spec_template_types.size > 1
|
621
|
-
print_red_alert "#{spec_template_types.size} spec template types found by code #{name}"
|
622
|
-
rows = spec_template_types.collect do |it|
|
623
|
-
{id: it['id'], code: it['code'], name: it['name']}
|
624
|
-
end
|
625
|
-
print "\n"
|
626
|
-
puts as_pretty_table(rows, [:id, :code, :name], {color:red})
|
627
|
-
return nil
|
628
|
-
else
|
629
|
-
return spec_template_types[0]
|
630
|
-
end
|
631
|
-
end
|
632
|
-
|
633
|
-
def find_spec_template_type_by_name_or_code_id(val)
|
634
|
-
if val.to_s =~ /\A\d{1,}\Z/
|
635
|
-
return find_subnet_by_id(val)
|
636
|
-
else
|
637
|
-
return find_spec_template_type_by_name_or_code(val)
|
638
|
-
end
|
639
|
-
end
|
558
|
+
|
640
559
|
|
641
|
-
def get_all_spec_template_types
|
642
|
-
@all_spec_template_types ||= @spec_template_types_interface.list({max: 1000})['specTemplateTypes'] || []
|
643
|
-
end
|
644
560
|
end
|
@@ -120,4 +120,173 @@ module Morpheus::Cli::LibraryHelper
|
|
120
120
|
return ports
|
121
121
|
end
|
122
122
|
|
123
|
+
## Spec Template helper methods
|
124
|
+
|
125
|
+
def find_spec_template_by_name_or_id(val)
|
126
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
127
|
+
return find_spec_template_by_id(val)
|
128
|
+
else
|
129
|
+
return find_spec_template_by_name(val)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def find_spec_template_by_id(id)
|
134
|
+
begin
|
135
|
+
json_response = @spec_templates_interface.get(id.to_i)
|
136
|
+
return json_response['specTemplate']
|
137
|
+
rescue RestClient::Exception => e
|
138
|
+
if e.response && e.response.code == 404
|
139
|
+
print_red_alert "Spec Template not found by id #{id}"
|
140
|
+
else
|
141
|
+
raise e
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def find_spec_template_by_name(name)
|
147
|
+
resource_specs = @spec_templates_interface.list({name: name.to_s})['specTemplates']
|
148
|
+
if resource_specs.empty?
|
149
|
+
print_red_alert "Spec Template not found by name #{name}"
|
150
|
+
return nil
|
151
|
+
elsif resource_specs.size > 1
|
152
|
+
print_red_alert "#{resource_specs.size} spec templates found by name #{name}"
|
153
|
+
print_resource_specs_table(resource_specs, {color: red})
|
154
|
+
print_red_alert "Try using ID instead"
|
155
|
+
print reset,"\n"
|
156
|
+
return nil
|
157
|
+
else
|
158
|
+
return resource_specs[0]
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def print_resource_specs_table(resource_specs, opts={})
|
163
|
+
columns = [
|
164
|
+
{"ID" => lambda {|resource_spec| resource_spec['id'] } },
|
165
|
+
{"NAME" => lambda {|resource_spec| resource_spec['name'] } },
|
166
|
+
#{"OWNER" => lambda {|resource_spec| resource_spec['account'] ? resource_spec['account']['name'] : '' } },
|
167
|
+
]
|
168
|
+
if opts[:include_fields]
|
169
|
+
columns = opts[:include_fields]
|
170
|
+
end
|
171
|
+
print as_pretty_table(resource_specs, columns, opts)
|
172
|
+
end
|
173
|
+
|
174
|
+
def find_spec_template_type_by_id(id)
|
175
|
+
begin
|
176
|
+
json_response = @spec_template_types_interface.get(id.to_i)
|
177
|
+
return json_response['networkType']
|
178
|
+
rescue RestClient::Exception => e
|
179
|
+
if e.response && e.response.code == 404
|
180
|
+
print_red_alert "Network Type not found by id #{id}"
|
181
|
+
return nil
|
182
|
+
else
|
183
|
+
raise e
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# def find_spec_template_type_by_name(name)
|
189
|
+
# json_response = @spec_template_types_interface.list({name: name.to_s})
|
190
|
+
# spec_template_types = json_response['networkTypes']
|
191
|
+
# if spec_template_types.empty?
|
192
|
+
# print_red_alert "Network Type not found by name #{name}"
|
193
|
+
# return spec_template_types
|
194
|
+
# elsif spec_template_types.size > 1
|
195
|
+
# print_red_alert "#{spec_template_types.size} network types found by name #{name}"
|
196
|
+
# rows = spec_template_types.collect do |it|
|
197
|
+
# {id: it['id'], name: it['name']}
|
198
|
+
# end
|
199
|
+
# puts as_pretty_table(rows, [:id, :name], {color:red})
|
200
|
+
# return nil
|
201
|
+
# else
|
202
|
+
# return spec_template_types[0]
|
203
|
+
# end
|
204
|
+
# end
|
205
|
+
|
206
|
+
def find_spec_template_type_by_name_or_code(name)
|
207
|
+
spec_template_types = get_all_spec_template_types().select { |it| name && it['code'] == name || it['name'] == name }
|
208
|
+
if spec_template_types.empty?
|
209
|
+
print_red_alert "Spec Template Type not found by code #{name}"
|
210
|
+
return nil
|
211
|
+
elsif spec_template_types.size > 1
|
212
|
+
print_red_alert "#{spec_template_types.size} spec template types found by code #{name}"
|
213
|
+
rows = spec_template_types.collect do |it|
|
214
|
+
{id: it['id'], code: it['code'], name: it['name']}
|
215
|
+
end
|
216
|
+
print "\n"
|
217
|
+
puts as_pretty_table(rows, [:id, :code, :name], {color:red})
|
218
|
+
return nil
|
219
|
+
else
|
220
|
+
return spec_template_types[0]
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
def find_spec_template_type_by_name_or_code_id(val)
|
225
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
226
|
+
return find_subnet_by_id(val)
|
227
|
+
else
|
228
|
+
return find_spec_template_type_by_name_or_code(val)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
def get_all_spec_template_types
|
233
|
+
@all_spec_template_types ||= @spec_template_types_interface.list({max: 1000})['specTemplateTypes'] || []
|
234
|
+
end
|
235
|
+
|
236
|
+
def prompt_for_spec_templates(params, options={}, api_client=nil, api_params={})
|
237
|
+
# spec_templates
|
238
|
+
spec_template_list = nil
|
239
|
+
spec_template_ids = nil
|
240
|
+
still_prompting = true
|
241
|
+
if params['specTemplates'].nil?
|
242
|
+
still_prompting = true
|
243
|
+
while still_prompting do
|
244
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'specTemplates', 'type' => 'text', 'fieldLabel' => 'Spec Templates', 'required' => false, 'description' => 'Spec Templates to include, comma separated list of names or IDs.'}], options[:options])
|
245
|
+
unless v_prompt['specTemplates'].to_s.empty?
|
246
|
+
spec_template_list = v_prompt['specTemplates'].split(",").collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
247
|
+
end
|
248
|
+
spec_template_ids = []
|
249
|
+
bad_ids = []
|
250
|
+
if spec_template_list && spec_template_list.size > 0
|
251
|
+
spec_template_list.each do |it|
|
252
|
+
found_spec_template = nil
|
253
|
+
begin
|
254
|
+
found_spec_template = find_spec_template_by_name_or_id(it)
|
255
|
+
rescue SystemExit => cmdexit
|
256
|
+
end
|
257
|
+
if found_spec_template
|
258
|
+
spec_template_ids << found_spec_template['id']
|
259
|
+
else
|
260
|
+
bad_ids << it
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
still_prompting = bad_ids.empty? ? false : true
|
265
|
+
end
|
266
|
+
else
|
267
|
+
spec_template_list = params['specTemplates']
|
268
|
+
still_prompting = false
|
269
|
+
spec_template_ids = []
|
270
|
+
bad_ids = []
|
271
|
+
if spec_template_list && spec_template_list.size > 0
|
272
|
+
spec_template_list.each do |it|
|
273
|
+
found_spec_template = nil
|
274
|
+
begin
|
275
|
+
found_spec_template = find_spec_template_by_name_or_id(it)
|
276
|
+
rescue SystemExit => cmdexit
|
277
|
+
end
|
278
|
+
if found_spec_template
|
279
|
+
spec_template_ids << found_spec_template['id']
|
280
|
+
else
|
281
|
+
bad_ids << it
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
if !bad_ids.empty?
|
286
|
+
return {success:false, msg:"Spec Templates not found: #{bad_ids}"}
|
287
|
+
end
|
288
|
+
end
|
289
|
+
return {success:true, data: spec_template_ids}
|
290
|
+
end
|
291
|
+
|
123
292
|
end
|
@@ -215,6 +215,9 @@ module Morpheus::Cli::PrintHelper
|
|
215
215
|
end
|
216
216
|
end
|
217
217
|
end
|
218
|
+
if options[:scrub]
|
219
|
+
output = Morpheus::Logging.scrub_message(output)
|
220
|
+
end
|
218
221
|
print_result = print_to_file(output, options[:outfile], options[:overwrite])
|
219
222
|
return print_result
|
220
223
|
end
|
@@ -244,7 +247,11 @@ module Morpheus::Cli::PrintHelper
|
|
244
247
|
end
|
245
248
|
end
|
246
249
|
puts "#{cyan}#{bold}#{dark}JSON#{reset}"
|
247
|
-
|
250
|
+
if options[:scrub]
|
251
|
+
print Morpheus::Logging.scrub_message(JSON.pretty_generate(payload))
|
252
|
+
else
|
253
|
+
print JSON.pretty_generate(payload)
|
254
|
+
end
|
248
255
|
else
|
249
256
|
print "Content-Type: #{content_type}", "\n"
|
250
257
|
print reset
|
@@ -252,7 +259,11 @@ module Morpheus::Cli::PrintHelper
|
|
252
259
|
pretty_size = "#{payload.size} B"
|
253
260
|
print "File: #{payload.path} (#{pretty_size})"
|
254
261
|
elsif payload.is_a?(String)
|
255
|
-
|
262
|
+
if options[:scrub]
|
263
|
+
print Morpheus::Logging.scrub_message(payload)
|
264
|
+
else
|
265
|
+
print payload
|
266
|
+
end
|
256
267
|
else
|
257
268
|
if content_type == 'application/x-www-form-urlencoded'
|
258
269
|
body_str = payload.to_s
|
@@ -261,9 +272,17 @@ module Morpheus::Cli::PrintHelper
|
|
261
272
|
rescue => ex
|
262
273
|
# raise ex
|
263
274
|
end
|
264
|
-
|
275
|
+
if options[:scrub]
|
276
|
+
print Morpheus::Logging.scrub_message(body_str)
|
277
|
+
else
|
278
|
+
print body_str
|
279
|
+
end
|
265
280
|
else
|
266
|
-
|
281
|
+
if options[:scrub]
|
282
|
+
print Morpheus::Logging.scrub_message(payload)
|
283
|
+
else
|
284
|
+
print payload
|
285
|
+
end
|
267
286
|
end
|
268
287
|
end
|
269
288
|
end
|
@@ -945,7 +964,11 @@ module Morpheus::Cli::PrintHelper
|
|
945
964
|
end
|
946
965
|
|
947
966
|
def format_boolean(v)
|
948
|
-
|
967
|
+
if v == true || v == "true" || v == "on"
|
968
|
+
"Yes"
|
969
|
+
else
|
970
|
+
"No"
|
971
|
+
end
|
949
972
|
end
|
950
973
|
|
951
974
|
def quote_csv_value(v)
|
data/lib/morpheus/cli/version.rb
CHANGED
data/lib/morpheus/logging.rb
CHANGED
@@ -92,6 +92,8 @@ module Morpheus::Logging
|
|
92
92
|
msg.gsub!(/#{header}\"\s?\=\>\s?\"[^"]+/, "#{header}\"=>\"************")
|
93
93
|
msg.gsub!(/#{header}\:\s?[^"'']+/, "#{header}: ************")
|
94
94
|
end
|
95
|
+
msg.gsub!(/password\"\: "[^"]+/, 'password": "************') # json properties ending with password
|
96
|
+
msg.gsub!(/Password\"\: "[^"]+/, 'Password": "************') # json properties ending with Password
|
95
97
|
msg.gsub!(/password\"\s?\=\>\s?\"[^"]+/i, 'password"=>"************')
|
96
98
|
msg.gsub!(/password\=\"[^"]+/i, 'password="************')
|
97
99
|
msg.gsub!(/password\=[^"'&\Z]+/i, 'password=************') # buggy, wont work with ampersand or quotes in passwords! heh
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: morpheus-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.1.
|
4
|
+
version: 4.1.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Estes
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2020-02-
|
14
|
+
date: 2020-02-11 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
@@ -439,8 +439,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
439
439
|
- !ruby/object:Gem::Version
|
440
440
|
version: '0'
|
441
441
|
requirements: []
|
442
|
-
|
443
|
-
rubygems_version: 2.7.6
|
442
|
+
rubygems_version: 3.0.6
|
444
443
|
signing_key:
|
445
444
|
specification_version: 4
|
446
445
|
summary: Provides CLI Interface to the Morpheus Public/Private Cloud Appliance
|