morpheus-cli 4.1.5 → 4.1.6
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/api/api_client.rb +4 -4
- data/lib/morpheus/api/network_subnets_interface.rb +1 -0
- data/lib/morpheus/api/security_groups_interface.rb +1 -1
- data/lib/morpheus/api/{network_subnet_types_interface.rb → subnet_types_interface.rb} +3 -3
- data/lib/morpheus/api/subnets_interface.rb +1 -1
- data/lib/morpheus/cli/appliance_settings_command.rb +1 -3
- data/lib/morpheus/cli/cli_command.rb +4 -0
- data/lib/morpheus/cli/credentials.rb +4 -5
- data/lib/morpheus/cli/error_handler.rb +8 -8
- data/lib/morpheus/cli/groups.rb +1 -1
- data/lib/morpheus/cli/license.rb +6 -12
- data/lib/morpheus/cli/mixins/infrastructure_helper.rb +375 -0
- data/lib/morpheus/cli/monitoring_alerts_command.rb +0 -2
- data/lib/morpheus/cli/network_groups_command.rb +116 -75
- data/lib/morpheus/cli/networks_command.rb +65 -767
- data/lib/morpheus/cli/remote.rb +1 -2
- data/lib/morpheus/cli/security_groups.rb +26 -33
- data/lib/morpheus/cli/shell.rb +12 -16
- data/lib/morpheus/cli/subnets_command.rb +708 -0
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/whitelabel_settings_command.rb +1 -3
- data/lib/morpheus/cli.rb +1 -0
- data/lib/morpheus/terminal.rb +1 -2
- metadata +4 -3
@@ -21,6 +21,8 @@ class Morpheus::Cli::NetworkGroupsCommand
|
|
21
21
|
def connect(opts)
|
22
22
|
@api_client = establish_remote_appliance_connection(opts)
|
23
23
|
@network_groups_interface = @api_client.network_groups
|
24
|
+
@networks_interface = @api_client.networks
|
25
|
+
@subnets_interface = @api_client.subnets
|
24
26
|
@clouds_interface = @api_client.clouds
|
25
27
|
@options_interface = @api_client.options
|
26
28
|
end
|
@@ -72,12 +74,13 @@ class Morpheus::Cli::NetworkGroupsCommand
|
|
72
74
|
description: network_group['description'],
|
73
75
|
# networks: network_group['networks'] ? network_group['networks'].collect {|it| it['name'] }.uniq.join(', ') : '',
|
74
76
|
networks: network_group['networks'] ? network_group['networks'].size : 0,
|
77
|
+
subnets: network_group['subnets'] ? network_group['subnets'].size : 0,
|
75
78
|
visibility: network_group['visibility'].to_s.capitalize,
|
76
79
|
tenants: network_group['tenants'] ? network_group['tenants'].collect {|it| it['name'] }.uniq.join(', ') : ''
|
77
80
|
}
|
78
81
|
row
|
79
82
|
}
|
80
|
-
columns = [:id, :name, :description, :networks, :visibility, :tenants]
|
83
|
+
columns = [:id, :name, :description, :networks, :subnets, :visibility, :tenants]
|
81
84
|
if options[:include_fields]
|
82
85
|
columns = options[:include_fields]
|
83
86
|
end
|
@@ -109,45 +112,79 @@ class Morpheus::Cli::NetworkGroupsCommand
|
|
109
112
|
return 1
|
110
113
|
end
|
111
114
|
connect(options)
|
115
|
+
exit_code, err = 0, nil
|
112
116
|
begin
|
117
|
+
network_group_id = nil
|
118
|
+
if args[0].to_s =~ /\A\d{1,}\Z/
|
119
|
+
network_group_id = args[0].to_i
|
120
|
+
else
|
121
|
+
network_group = find_network_group_by_name(args[0])
|
122
|
+
return 1, "Network Group not found" if network_group.nil?
|
123
|
+
network_group_id = network_group['id']
|
124
|
+
end
|
113
125
|
@network_groups_interface.setopts(options)
|
114
126
|
if options[:dry_run]
|
115
|
-
|
116
|
-
|
117
|
-
else
|
118
|
-
print_dry_run @network_groups_interface.dry.list({name:args[0]})
|
119
|
-
end
|
120
|
-
return
|
127
|
+
print_dry_run @network_groups_interface.dry.get(network_group_id)
|
128
|
+
return exit_code, err
|
121
129
|
end
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
130
|
+
json_response = @network_groups_interface.get(network_group_id)
|
131
|
+
render_result = render_with_format(json_response, options, 'networkGroup')
|
132
|
+
return exit_code, err if render_result
|
133
|
+
|
126
134
|
network_group = json_response['networkGroup']
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
elsif options[:yaml]
|
131
|
-
puts as_yaml(json_response, options, "networkGroup")
|
132
|
-
return 0
|
133
|
-
elsif options[:csv]
|
134
|
-
puts records_as_csv([network_group], options)
|
135
|
-
return 0
|
136
|
-
end
|
135
|
+
networks = json_response['networks'] # || network_group['networks']
|
136
|
+
subnets = json_response['subnets'] # || network_group['subnets']
|
137
|
+
|
137
138
|
print_h1 "Network Group Details"
|
138
139
|
print cyan
|
139
140
|
description_cols = {
|
140
141
|
"ID" => 'id',
|
141
142
|
"Name" => 'name',
|
142
143
|
"Description" => 'description',
|
143
|
-
"Networks" => lambda {|it| it['networks']
|
144
|
+
"Networks" => lambda {|it| it['networks'].size rescue 'n/a' },
|
145
|
+
"Subnets" => lambda {|it| it['subnets'].size rescue 'n/a' },
|
144
146
|
"Visibility" => lambda {|it| it['visibility'].to_s.capitalize },
|
145
147
|
"Tenants" => lambda {|it| it['tenants'] ? it['tenants'].collect {|it| it['name'] }.uniq.join(', ') : '' },
|
146
148
|
# "Owner" => lambda {|it| it['owner'] ? it['owner']['name'] : '' },
|
147
149
|
}
|
148
150
|
print_description_list(description_cols, network_group)
|
149
151
|
|
150
|
-
|
152
|
+
if networks.empty?
|
153
|
+
# print cyan,"No networks found.",reset,"\n"
|
154
|
+
else
|
155
|
+
print_h2 "Networks"
|
156
|
+
subnet_columns = {
|
157
|
+
"ID" => 'id',
|
158
|
+
"Name" => 'name',
|
159
|
+
#"Description" => 'description',
|
160
|
+
"Type" => lambda {|it| it['type']['name'] rescue it['type'] },
|
161
|
+
"CIDR" => lambda {|it| it['cidr'] },
|
162
|
+
"Visibility" => lambda {|it| it['visibility'].to_s.capitalize },
|
163
|
+
"Tenants" => lambda {|it| it['tenants'] ? it['tenants'].collect {|it| it['name'] }.uniq.join(', ') : '' }
|
164
|
+
}
|
165
|
+
print cyan
|
166
|
+
print as_pretty_table(networks, subnet_columns)
|
167
|
+
print reset,"\n"
|
168
|
+
end
|
169
|
+
|
170
|
+
if subnets.empty?
|
171
|
+
# print cyan,"No subnets found.",reset,"\n"
|
172
|
+
else
|
173
|
+
print_h2 "Subnets"
|
174
|
+
subnet_columns = {
|
175
|
+
"ID" => 'id',
|
176
|
+
"Name" => 'name',
|
177
|
+
#"Description" => 'description',
|
178
|
+
"Type" => lambda {|it| it['type']['name'] rescue it['type'] },
|
179
|
+
"CIDR" => lambda {|it| it['cidr'] },
|
180
|
+
"Visibility" => lambda {|it| it['visibility'].to_s.capitalize },
|
181
|
+
"Tenants" => lambda {|it| it['tenants'] ? it['tenants'].collect {|it| it['name'] }.uniq.join(', ') : '' }
|
182
|
+
}
|
183
|
+
print cyan
|
184
|
+
print as_pretty_table(subnets, subnet_columns)
|
185
|
+
print reset,"\n"
|
186
|
+
end
|
187
|
+
|
151
188
|
if network_group['resourcePermission'].nil?
|
152
189
|
print "\n", "No group access found", "\n"
|
153
190
|
else
|
@@ -167,9 +204,9 @@ class Morpheus::Cli::NetworkGroupsCommand
|
|
167
204
|
columns = [:group, :default]
|
168
205
|
print cyan
|
169
206
|
print as_pretty_table(rows, columns)
|
207
|
+
print reset,"\n"
|
170
208
|
end
|
171
209
|
|
172
|
-
print reset,"\n"
|
173
210
|
return 0
|
174
211
|
rescue RestClient::Exception => e
|
175
212
|
print_rest_exception(e, options)
|
@@ -191,13 +228,20 @@ class Morpheus::Cli::NetworkGroupsCommand
|
|
191
228
|
opts.on('--description VALUE', String, "Description of network group") do |val|
|
192
229
|
options['description'] = val
|
193
230
|
end
|
194
|
-
opts.on('--networks LIST', Array, "Networks in the group, comma separated list of network IDs") do |list|
|
195
|
-
if list.size == 1 &&
|
231
|
+
opts.on('--networks LIST', Array, "Networks in the group, comma separated list of network names or IDs") do |list|
|
232
|
+
if list.size == 1 && ('[]' == list[0]) # clear array
|
196
233
|
options['networks'] = []
|
197
234
|
else
|
198
235
|
options['networks'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
199
236
|
end
|
200
237
|
end
|
238
|
+
opts.on('--subnets LIST', Array, "Subnets, comma separated list of names or IDs.") do |list|
|
239
|
+
if list.size == 1 && ('[]' == list[0]) # clear array
|
240
|
+
options['subnets'] = []
|
241
|
+
else
|
242
|
+
options['subnets'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
243
|
+
end
|
244
|
+
end
|
201
245
|
opts.on('--group-access-all [on|off]', String, "Toggle Access for all groups.") do |val|
|
202
246
|
group_access_all = val.to_s == 'on' || val.to_s == 'true'
|
203
247
|
end
|
@@ -284,12 +328,29 @@ class Morpheus::Cli::NetworkGroupsCommand
|
|
284
328
|
end
|
285
329
|
|
286
330
|
# Networks
|
287
|
-
if options['networks']
|
288
|
-
|
331
|
+
# if options['networks']
|
332
|
+
# payload['networkGroup']['networks'] = options['networks'].collect {|it| {id: it} }
|
333
|
+
# else
|
334
|
+
# v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'networks', 'fieldLabel' => 'Networks', 'type' => 'text', 'required' => true, 'description' => 'Networks in the group, comma separated list of network IDs.'}], options)
|
335
|
+
# payload['networkGroup']['networks'] = v_prompt['networks'].to_s.split(",").collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq.collect {|it| {id: it} }
|
336
|
+
# end
|
337
|
+
|
338
|
+
# Networks
|
339
|
+
prompt_results = prompt_for_networks(options, options, @api_client)
|
340
|
+
if prompt_results[:success]
|
341
|
+
payload['networkGroup']['networks'] = prompt_results[:data] unless prompt_results[:data].nil?
|
342
|
+
else
|
343
|
+
return 1, "Networks prompt failed."
|
344
|
+
end
|
345
|
+
|
346
|
+
# Subnets
|
347
|
+
prompt_results = prompt_for_subnets(options, options, @api_client)
|
348
|
+
if prompt_results[:success]
|
349
|
+
payload['networkGroup']['subnets'] = prompt_results[:data] unless prompt_results[:data].nil?
|
289
350
|
else
|
290
|
-
|
291
|
-
payload['networkGroup']['networks'] = v_prompt['networks'].to_s.split(",").collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq.collect {|it| {id: it} }
|
351
|
+
return 1, "Subnets prompt failed."
|
292
352
|
end
|
353
|
+
|
293
354
|
|
294
355
|
# Group Access
|
295
356
|
if group_access_all != nil
|
@@ -362,6 +423,13 @@ class Morpheus::Cli::NetworkGroupsCommand
|
|
362
423
|
options['networks'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
363
424
|
end
|
364
425
|
end
|
426
|
+
opts.on('--subnets LIST', Array, "Subnets, comma separated list of names or IDs.") do |list|
|
427
|
+
if list.size == 1 && ('[]' == list[0]) # clear array
|
428
|
+
options['subnets'] = []
|
429
|
+
else
|
430
|
+
options['subnets'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
431
|
+
end
|
432
|
+
end
|
365
433
|
opts.on('--group-access-all [on|off]', String, "Toggle Access for all groups.") do |val|
|
366
434
|
group_access_all = val.to_s == 'on' || val.to_s == 'true'
|
367
435
|
end
|
@@ -444,13 +512,25 @@ class Morpheus::Cli::NetworkGroupsCommand
|
|
444
512
|
# v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'required' => false, 'description' => 'Description of network group.'}], options)
|
445
513
|
# payload['networkGroup']['description'] = v_prompt['description']
|
446
514
|
end
|
447
|
-
|
515
|
+
|
448
516
|
# Networks
|
449
517
|
if options['networks']
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
518
|
+
prompt_results = prompt_for_networks(options, options, @api_client)
|
519
|
+
if prompt_results[:success]
|
520
|
+
payload['networkGroup']['networks'] = prompt_results[:data] unless prompt_results[:data].nil?
|
521
|
+
else
|
522
|
+
return 1, "Networks prompt failed."
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
# Subnets
|
527
|
+
if options['subnets']
|
528
|
+
prompt_results = prompt_for_subnets(options, options, @api_client)
|
529
|
+
if prompt_results[:success]
|
530
|
+
payload['networkGroup']['subnets'] = prompt_results[:data] unless prompt_results[:data].nil?
|
531
|
+
else
|
532
|
+
return 1, "Subnets prompt failed."
|
533
|
+
end
|
454
534
|
end
|
455
535
|
|
456
536
|
# Group Access
|
@@ -548,45 +628,6 @@ class Morpheus::Cli::NetworkGroupsCommand
|
|
548
628
|
private
|
549
629
|
|
550
630
|
|
551
|
-
|
552
|
-
if val.to_s =~ /\A\d{1,}\Z/
|
553
|
-
return find_network_group_by_id(val)
|
554
|
-
else
|
555
|
-
return find_network_group_by_name(val)
|
556
|
-
end
|
557
|
-
end
|
558
|
-
|
559
|
-
def find_network_group_by_id(id)
|
560
|
-
begin
|
561
|
-
json_response = @network_groups_interface.get(id.to_i)
|
562
|
-
return json_response['networkGroup']
|
563
|
-
rescue RestClient::Exception => e
|
564
|
-
if e.response && e.response.code == 404
|
565
|
-
print_red_alert "Network Group not found by id #{id}"
|
566
|
-
return nil
|
567
|
-
else
|
568
|
-
raise e
|
569
|
-
end
|
570
|
-
end
|
571
|
-
end
|
572
|
-
|
573
|
-
def find_network_group_by_name(name)
|
574
|
-
json_response = @network_groups_interface.list({name: name.to_s})
|
575
|
-
network_groups = json_response['networkGroups']
|
576
|
-
if network_groups.empty?
|
577
|
-
print_red_alert "Network Group not found by name #{name}"
|
578
|
-
return nil
|
579
|
-
elsif network_groups.size > 1
|
580
|
-
print_red_alert "#{network_groups.size} network groups found by name #{name}"
|
581
|
-
# print_networks_table(networks, {color: red})
|
582
|
-
rows = network_groups.collect do |it|
|
583
|
-
{id: it['id'], name: it['name']}
|
584
|
-
end
|
585
|
-
puts as_pretty_table(rows, [:id, :name], {color:red})
|
586
|
-
return nil
|
587
|
-
else
|
588
|
-
return network_groups[0]
|
589
|
-
end
|
590
|
-
end
|
631
|
+
|
591
632
|
|
592
633
|
end
|