enfcli 3.3.2.pre.alpha
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 +7 -0
- data/.circleci/Dockerfile +11 -0
- data/.circleci/build.sh +74 -0
- data/.circleci/config.yml +108 -0
- data/.circleci/setup-rubygems.sh +3 -0
- data/.gitignore +51 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +81 -0
- data/LICENSE +201 -0
- data/Makefile +28 -0
- data/README.md +67 -0
- data/Rakefile +14 -0
- data/bin/enfcli +5 -0
- data/enfcli.gemspec +46 -0
- data/lib/enfapi.rb +398 -0
- data/lib/enfcli/commands/user.rb +185 -0
- data/lib/enfcli/commands/xcr.rb +480 -0
- data/lib/enfcli/commands/xfw.rb +151 -0
- data/lib/enfcli/commands/xiam.rb +562 -0
- data/lib/enfcli/version.rb +18 -0
- data/lib/enfcli.rb +390 -0
- data/lib/enfthor.rb +118 -0
- metadata +218 -0
@@ -0,0 +1,480 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2018 Xaptum,Inc
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
require 'enfthor'
|
17
|
+
require 'enfapi'
|
18
|
+
|
19
|
+
module EnfCli
|
20
|
+
|
21
|
+
module Cmd
|
22
|
+
|
23
|
+
class Xcr < EnfThor
|
24
|
+
no_commands {
|
25
|
+
def display_endpoints eps
|
26
|
+
headings = ['IPV6', 'Name', 'State', 'Network', 'Remote IP']
|
27
|
+
rows = eps.map{ |hash|
|
28
|
+
[ hash[:ipv6],
|
29
|
+
hash[:name],
|
30
|
+
hash[:state],
|
31
|
+
hash[:state] == 'OFFLINE' ? '' : hash[:ev_asn_org],
|
32
|
+
hash[:state] == 'OFFLINE' ? '' : hash[:ev_remote_ip]
|
33
|
+
]
|
34
|
+
}
|
35
|
+
render_table(headings, rows, options.file)
|
36
|
+
end
|
37
|
+
|
38
|
+
def display_endpoint_events events
|
39
|
+
headings = ['Time', 'IPV6', 'Source', 'Event', 'Network', 'Remote IP']
|
40
|
+
rows = events.map{ |hash|
|
41
|
+
[ hash[:inserted_date], hash[:ipv6_text], hash[:source], hash[:type], hash[:asn_org], hash[:remote_ip]]
|
42
|
+
}
|
43
|
+
render_table(headings, rows)
|
44
|
+
end
|
45
|
+
|
46
|
+
def display_domains domains
|
47
|
+
headings = ['Name', 'Network', 'Status']
|
48
|
+
rows = domains.map{ |hash|
|
49
|
+
[ hash[:name], hash[:network], hash[:status]
|
50
|
+
]
|
51
|
+
}
|
52
|
+
render_table(headings, rows)
|
53
|
+
end
|
54
|
+
|
55
|
+
def display_networks networks
|
56
|
+
headings = ['Name', 'Network', 'Description', 'Status']
|
57
|
+
rows = networks.map{ |hash|
|
58
|
+
[ hash[:name], hash[:network], hash[:description], hash[:status]
|
59
|
+
]
|
60
|
+
}
|
61
|
+
render_table(headings, rows)
|
62
|
+
end
|
63
|
+
|
64
|
+
def display_limits limits
|
65
|
+
# Extract default limits
|
66
|
+
default_limits = limits[:default]
|
67
|
+
current_limits = limits[:current]
|
68
|
+
max_limits = limits[:max]
|
69
|
+
|
70
|
+
# add type to the limits hash
|
71
|
+
default_limits[:limit] = 'DEFAULT' if default_limits
|
72
|
+
max_limits[:limit] = 'MAX' if max_limits
|
73
|
+
current_limits[:limit] = 'CURRENT' if current_limits
|
74
|
+
|
75
|
+
limits_array = []
|
76
|
+
limits_array.push default_limits if default_limits
|
77
|
+
limits_array.push current_limits if current_limits
|
78
|
+
limits_array.push max_limits if max_limits
|
79
|
+
|
80
|
+
headings = ['Limit', 'Pkts/Sec', 'Pkts Burst Size', 'Bytes/Sec', 'Bytes Burst Size', 'Inherited']
|
81
|
+
rows = limits_array.map{ |hash|
|
82
|
+
[ hash[:limit], hash[:packets_per_second], hash[:packets_burst_size], hash[:bytes_per_second], hash[:bytes_burst_size],
|
83
|
+
hash[:inherit] ? hash[:inherit] : "N/A"
|
84
|
+
]
|
85
|
+
}
|
86
|
+
render_table(headings, rows)
|
87
|
+
end
|
88
|
+
}
|
89
|
+
|
90
|
+
desc "list-networks", "List all virtual networks in domain"
|
91
|
+
def list_networks
|
92
|
+
try_with_rescue_in_session do
|
93
|
+
domain_id = EnfCli::CTX.instance.session[:domain_id]
|
94
|
+
|
95
|
+
# Call the api
|
96
|
+
data = EnfApi::API.instance.list_domain_nws domain_id
|
97
|
+
networks = data[:data]
|
98
|
+
|
99
|
+
# display table
|
100
|
+
display_networks networks
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
desc "provision-network", "Provision a Network"
|
105
|
+
method_option :name, :type => :array, :required => true, :banner => "NAME"
|
106
|
+
method_option :description, :type => :array, :banner => "DESCRIPTION"
|
107
|
+
def provision_network
|
108
|
+
try_with_rescue_in_session do
|
109
|
+
# verify domain context is set
|
110
|
+
domain_id = EnfCli::CTX.instance.session[:domain_id]
|
111
|
+
raise EnfCli::ERROR, "User's domain not available!" if !domain_id || domain_id < 0
|
112
|
+
|
113
|
+
# Get options
|
114
|
+
description = ""
|
115
|
+
network_name = options.name.join(" ").gsub(/\A"+(.*?)"+\Z/m, '\1')
|
116
|
+
description = options.description.join(" ").gsub(/\A"+(.*?)"+\Z/m, '\1') if options.description
|
117
|
+
|
118
|
+
# Call the api
|
119
|
+
hash = {
|
120
|
+
:name => network_name,
|
121
|
+
:domain_id => domain_id,
|
122
|
+
:description => description
|
123
|
+
}
|
124
|
+
data = EnfApi::API.instance.create_nw hash
|
125
|
+
networks = data[:data]
|
126
|
+
|
127
|
+
# display table
|
128
|
+
say "Provisioned a network!", :green
|
129
|
+
display_networks networks
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
desc "list-enf-networks", "List enf /34 networks"
|
134
|
+
def list_enf_networks
|
135
|
+
try_with_rescue_in_session do
|
136
|
+
# Call the api
|
137
|
+
data = EnfApi::API.instance.list_enfnws
|
138
|
+
networks = data[:data]
|
139
|
+
|
140
|
+
# Display the data
|
141
|
+
headings = ['Id', 'Parent', 'Network', 'Notes', 'Status', 'Type']
|
142
|
+
rows = networks.map{ |hash|
|
143
|
+
[ hash[:id], hash[:parent], hash[:network], hash[:notes], hash[:status], hash[:type] ]
|
144
|
+
}
|
145
|
+
render_table(headings, rows)
|
146
|
+
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
desc "list-domains", "List all domains"
|
151
|
+
def list_domains
|
152
|
+
try_with_rescue_in_session do
|
153
|
+
session = EnfCli::CTX.instance.session
|
154
|
+
|
155
|
+
# call api
|
156
|
+
data = {:data => []}
|
157
|
+
case session[:type]
|
158
|
+
when 'XAPTUM_ADMIN'
|
159
|
+
data = EnfApi::API.instance.list_domains
|
160
|
+
|
161
|
+
when 'DOMAIN_ADMIN'
|
162
|
+
data = EnfApi::API.instance.get_domain session[:domain_id]
|
163
|
+
end
|
164
|
+
|
165
|
+
# Display the data
|
166
|
+
domains = data[:data]
|
167
|
+
display_domains domains
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
desc "provision-domain", "Provision a new customer /48 network domain"
|
172
|
+
method_option :name, :type => :string, :required => true
|
173
|
+
method_option :'admin-name', :type => :array, :required => true, :banner => "ADMIN_NAME"
|
174
|
+
method_option :'admin-email', :type => :string, :required => true, :banner => "EMAIL"
|
175
|
+
def provision_domain
|
176
|
+
try_with_rescue_in_session do
|
177
|
+
# Get cli params
|
178
|
+
domain_name = options[:name]
|
179
|
+
admin_name = options[:'admin-name'].join(" ").gsub(/\A"+(.*?)"+\Z/m, '\1')
|
180
|
+
admin_email = options[:'admin-email']
|
181
|
+
|
182
|
+
# Call api
|
183
|
+
hash = {
|
184
|
+
:admin_name => admin_name,
|
185
|
+
:admin_email => admin_email,
|
186
|
+
:name => domain_name,
|
187
|
+
:type => 'CUSTOMER_SOURCE'
|
188
|
+
}
|
189
|
+
data = EnfApi::API.instance.create_domain hash
|
190
|
+
|
191
|
+
# Display the data
|
192
|
+
domains = data[:data]
|
193
|
+
display_domains domains
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
desc "list-domain-rate-limits", "List domain rate limits"
|
198
|
+
method_option :network, :type => :string, :required => true, :banner => '</48 Network>'
|
199
|
+
method_option :filter, :type => :string, :enum => ['default', 'max']
|
200
|
+
def list_domain_rate_limits
|
201
|
+
try_with_rescue_in_session do
|
202
|
+
# Call the api
|
203
|
+
data = EnfApi::API.instance.get_domain_rate_limits options[:network], options[:filter]
|
204
|
+
|
205
|
+
# Get the limits
|
206
|
+
limits = data[:data][0]
|
207
|
+
|
208
|
+
# Display limits
|
209
|
+
display_limits limits
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
desc "list-network-rate-limits", "List network rate limits"
|
214
|
+
method_option :network, :type => :string, :required => true
|
215
|
+
method_option :filter, :type => :string, :enum => ['default', 'max']
|
216
|
+
def list_network_rate_limits
|
217
|
+
try_with_rescue_in_session do
|
218
|
+
# Call the api
|
219
|
+
data = EnfApi::API.instance.get_network_rate_limits options[:network], options[:filter]
|
220
|
+
|
221
|
+
# Get the limits
|
222
|
+
limits = data[:data][0]
|
223
|
+
|
224
|
+
# Display limits
|
225
|
+
display_limits limits
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
desc "list-endpoint-rate-limits", "List endpoints rate limits"
|
230
|
+
method_option :ipv6, :type => :string, :required => true
|
231
|
+
method_option :filter, :type => :string, :enum => ['current', 'max']
|
232
|
+
def list_endpoint_rate_limits
|
233
|
+
try_with_rescue_in_session do
|
234
|
+
# Call the api
|
235
|
+
data = EnfApi::API.instance.get_ep_rate_limits options[:ipv6], options[:filter]
|
236
|
+
|
237
|
+
# Get the limits
|
238
|
+
limits = data[:data][0]
|
239
|
+
|
240
|
+
# Display limits
|
241
|
+
display_limits limits
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
desc "activate-domain", "Activate a customer's /48 domain"
|
246
|
+
method_option :network, :type => :string, :required => true
|
247
|
+
def activate_domain
|
248
|
+
try_with_rescue_in_session do
|
249
|
+
# Call api
|
250
|
+
data = EnfApi::API.instance.activate_domain options[:network]
|
251
|
+
domains = data[:data]
|
252
|
+
|
253
|
+
# Display the data
|
254
|
+
say "Activated Domain!", :green
|
255
|
+
display_domains domains
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
desc "deactivate-domain", "Deactivate a customer's /48 domain"
|
260
|
+
method_option :network, :type => :string, :required => true
|
261
|
+
def deactivate_domain
|
262
|
+
try_with_rescue_in_session do
|
263
|
+
# Call api
|
264
|
+
data = EnfApi::API.instance.deactivate_domain options[:network]
|
265
|
+
domains = data[:data]
|
266
|
+
|
267
|
+
# Display the data
|
268
|
+
say "Deactivated Domain!", :yellow
|
269
|
+
display_domains domains
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
desc "set-domain-rate-limits", "Update a customer /48 domain's endpoint rate limits"
|
274
|
+
method_option :network, :type => :string, :required => true
|
275
|
+
method_option :limit, :type => :string, :enum => ['default', 'max'], :required => true
|
276
|
+
method_option :'packets-per-second', :type => :numeric, :required => true
|
277
|
+
method_option :'packets-burst-size', :type => :numeric, :required => true
|
278
|
+
method_option :'bytes-per-second', :type => :numeric, :required => true
|
279
|
+
method_option :'bytes-burst-size', :type => :numeric, :required => true
|
280
|
+
def set_domain_rate_limits
|
281
|
+
try_with_rescue_in_session do
|
282
|
+
# Call api
|
283
|
+
hash = {
|
284
|
+
:packets_per_second => options['packets-per-second'],
|
285
|
+
:packets_burst_size => options['packets-burst-size'],
|
286
|
+
:bytes_per_second => options['bytes-per-second'],
|
287
|
+
:bytes_burst_size => options['bytes-burst-size']
|
288
|
+
}
|
289
|
+
data = EnfApi::API.instance.update_domain_rate_limits options[:network], options[:limit], hash
|
290
|
+
limits = data[:data][0]
|
291
|
+
|
292
|
+
# The Api returns only the rate limits object. Have to add type explicitly to display
|
293
|
+
limits_hash = {
|
294
|
+
options[:limit].to_sym => limits
|
295
|
+
}
|
296
|
+
display_limits limits_hash
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
desc "set-network-rate-limits", "Update a customer /64 network's endpoint rate limits"
|
301
|
+
method_option :network, :type => :string, :required => true
|
302
|
+
method_option :limit, :type => :string, :enum => ['default', 'max'], :required => true
|
303
|
+
method_option :'packets-per-second', :type => :numeric, :required => true
|
304
|
+
method_option :'packets-burst-size', :type => :numeric, :required => true
|
305
|
+
method_option :'bytes-per-second', :type => :numeric, :required => true
|
306
|
+
method_option :'bytes-burst-size', :type => :numeric, :required => true
|
307
|
+
def set_network_rate_limits
|
308
|
+
try_with_rescue_in_session do
|
309
|
+
# Call api
|
310
|
+
hash = {
|
311
|
+
:packets_per_second => options['packets-per-second'],
|
312
|
+
:packets_burst_size => options['packets-burst-size'],
|
313
|
+
:bytes_per_second => options['bytes-per-second'],
|
314
|
+
:bytes_burst_size => options['bytes-burst-size']
|
315
|
+
}
|
316
|
+
data = EnfApi::API.instance.update_network_rate_limits options[:network], options[:limit], hash
|
317
|
+
limits = data[:data][0]
|
318
|
+
|
319
|
+
# The Api returns only the rate limits object. Have to add type explicitly to display
|
320
|
+
limits_hash = {
|
321
|
+
options[:limit].to_sym => limits
|
322
|
+
}
|
323
|
+
display_limits limits_hash
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
desc "reset-network-rate-limits", "Reset customer /64 network's endpoint rate limits to domains rate limits"
|
328
|
+
method_option :network, :type => :string, :required => true
|
329
|
+
method_option :limit, :type => :string, :enum => ['default', 'max'], :required => true
|
330
|
+
def reset_network_rate_limits
|
331
|
+
try_with_rescue_in_session do
|
332
|
+
# Call api
|
333
|
+
hash = {
|
334
|
+
:inherit => 'Y'
|
335
|
+
}
|
336
|
+
data = EnfApi::API.instance.update_network_rate_limits options[:network], options[:limit], hash
|
337
|
+
limits = data[:data][0]
|
338
|
+
|
339
|
+
# The Api returns only the rate limits object. Have to add type explicitly to display
|
340
|
+
limits_hash = {
|
341
|
+
options[:limit].to_sym => limits
|
342
|
+
}
|
343
|
+
display_limits limits_hash
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
desc "set-endpoint-rate-limits", "Update an ipv6 endpoint rate limits"
|
348
|
+
method_option :ipv6, :type => :string, :required => true
|
349
|
+
method_option :limit, :type => :string, :enum => ['current', 'max'], :required => true
|
350
|
+
method_option :'packets-per-second', :type => :numeric, :required => true
|
351
|
+
method_option :'packets-burst-size', :type => :numeric, :required => true
|
352
|
+
method_option :'bytes-per-second', :type => :numeric, :required => true
|
353
|
+
method_option :'bytes-burst-size', :type => :numeric, :required => true
|
354
|
+
def set_endpoint_rate_limits
|
355
|
+
try_with_rescue_in_session do
|
356
|
+
# Call api
|
357
|
+
hash = {
|
358
|
+
:packets_per_second => options['packets-per-second'],
|
359
|
+
:packets_burst_size => options['packets-burst-size'],
|
360
|
+
:bytes_per_second => options['bytes-per-second'],
|
361
|
+
:bytes_burst_size => options['bytes-burst-size']
|
362
|
+
}
|
363
|
+
data = EnfApi::API.instance.update_ep_rate_limits options[:ipv6], options[:limit], hash
|
364
|
+
limits = data[:data][0]
|
365
|
+
|
366
|
+
# The Api returns only the rate limits object. Have to add type explicitly to display
|
367
|
+
limits_hash = {
|
368
|
+
options[:limit].to_sym => limits
|
369
|
+
}
|
370
|
+
display_limits limits_hash
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
desc "reset-endpoint-rate-limits", "Reset an ipv6 endpoint rate limits to network's rate limits"
|
375
|
+
method_option :ipv6, :type => :string, :required => true
|
376
|
+
method_option :limit, :type => :string, :enum => ['current', 'max'], :required => true
|
377
|
+
def reset_endpoint_rate_limits
|
378
|
+
try_with_rescue_in_session do
|
379
|
+
# Call api
|
380
|
+
hash = {
|
381
|
+
:inherit => 'Y'
|
382
|
+
}
|
383
|
+
data = EnfApi::API.instance.update_ep_rate_limits options[:ipv6], options[:limit], hash
|
384
|
+
limits = data[:data][0]
|
385
|
+
|
386
|
+
# The Api returns only the rate limits object. Have to add type explicitly to display
|
387
|
+
limits_hash = {
|
388
|
+
options[:limit].to_sym => limits
|
389
|
+
}
|
390
|
+
display_limits limits_hash
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
desc "list-endpoints", "List all connections in a network"
|
395
|
+
method_option :network, :type => :string, :required => true
|
396
|
+
method_option :file, :type => :string, :aliases => "-f"
|
397
|
+
def list_endpoints
|
398
|
+
try_with_rescue_in_session do
|
399
|
+
# verify domain context is set
|
400
|
+
domain_id = EnfCli::CTX.instance.session[:domain_id]
|
401
|
+
raise EnfCli::ERROR, "User's domain not available!" if !domain_id || domain_id < 0
|
402
|
+
|
403
|
+
# call api
|
404
|
+
data = EnfApi::API.instance.list_nw_connections domain_id, options.network, options.file
|
405
|
+
cxns = data[:data]
|
406
|
+
|
407
|
+
# display table
|
408
|
+
display_endpoints cxns
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
desc "list-endpoint-events", "List connect/disconnect events for an ipv6 endpoint"
|
413
|
+
method_option :ipv6, :type => :string, :required => true
|
414
|
+
def list_endpoint_events
|
415
|
+
try_with_rescue_in_session do
|
416
|
+
# call the api
|
417
|
+
data = EnfApi::API.instance.list_endpoint_events options.ipv6
|
418
|
+
events = data[:data]
|
419
|
+
|
420
|
+
# display data
|
421
|
+
display_endpoint_events events
|
422
|
+
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
desc "list-network-events", "List connect/disconnect events of ipv6 endpoints in a network"
|
427
|
+
method_option :network, :type => :string, :required => true
|
428
|
+
def list_network_events
|
429
|
+
try_with_rescue_in_session do
|
430
|
+
# call the api
|
431
|
+
data = EnfApi::API.instance.list_network_events options.network
|
432
|
+
events = data[:data]
|
433
|
+
|
434
|
+
# display data
|
435
|
+
display_endpoint_events events
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
desc "get-endpoint", "Display an ipv6 endpoint's information"
|
440
|
+
method_option :ipv6, :type => :string, :required => true
|
441
|
+
def get_endpoint
|
442
|
+
try_with_rescue_in_session do
|
443
|
+
# call the api
|
444
|
+
data = EnfApi::API.instance.get_endpoint options.ipv6
|
445
|
+
eps = data[:data]
|
446
|
+
|
447
|
+
# display data
|
448
|
+
display_endpoints eps
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
desc "update-endpoint", "Update an ipv6 endpoint's name"
|
453
|
+
method_option :ipv6, :type => :string, :required => true
|
454
|
+
method_option :name, :type => :array, :required => true, :banner => "NAME"
|
455
|
+
def update_endpoint
|
456
|
+
try_with_rescue_in_session do
|
457
|
+
# Call the api
|
458
|
+
data = EnfApi::API.instance.update_endpoint options.ipv6, options.name.join(" ").gsub(/\A"+(.*?)"+\Z/m, '\1')
|
459
|
+
eps = data[:data]
|
460
|
+
|
461
|
+
# display data
|
462
|
+
display_endpoints eps
|
463
|
+
end
|
464
|
+
end
|
465
|
+
|
466
|
+
desc "activate-enf-network", "Active a /34 enf network"
|
467
|
+
method_option :network, :type => :string, :required => true
|
468
|
+
def activate_enfnw
|
469
|
+
try_with_rescue_in_session do
|
470
|
+
# Call the api
|
471
|
+
EnfApi::API.instance.activate_enfnw options.network
|
472
|
+
|
473
|
+
# Print success
|
474
|
+
say "Activated Enf Network #{options.network}!", :green
|
475
|
+
end
|
476
|
+
end
|
477
|
+
|
478
|
+
end # class
|
479
|
+
end # module Cmd
|
480
|
+
end # module EnfCli
|
@@ -0,0 +1,151 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2018 Xaptum,Inc
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
require 'enfthor'
|
17
|
+
require 'enfapi'
|
18
|
+
require 'base64'
|
19
|
+
require 'digest'
|
20
|
+
require 'openssl'
|
21
|
+
require 'ipaddr'
|
22
|
+
|
23
|
+
module EnfCli
|
24
|
+
module Cmd
|
25
|
+
|
26
|
+
class Xfw < EnfThor
|
27
|
+
no_commands {
|
28
|
+
def display_firewall_rules rules
|
29
|
+
headings = ['Id', 'Priority', 'Protocol', 'Direction', 'Source', 'Source Port', 'Destination', 'Destination Port', 'Action']
|
30
|
+
rows = rules.map{ |hash|
|
31
|
+
[ hash[:id], hash[:priority], hash[:protocol], hash[:direction],
|
32
|
+
hash[:source_ip] == '' ? '*' : hash[:source_ip],
|
33
|
+
hash[:source_port] == 0 ? '*' : hash[:source_port],
|
34
|
+
hash[:dest_ip] == '' ? '*' : hash[:dest_ip],
|
35
|
+
hash[:dest_port] == 0 ? '*' : hash[:dest_port],
|
36
|
+
hash[:action] ]
|
37
|
+
}
|
38
|
+
render_table(headings, rows)
|
39
|
+
end
|
40
|
+
}
|
41
|
+
|
42
|
+
desc "list-firewall-rules", "List all firewall rules in a /64 network"
|
43
|
+
method_option :network, :type => :string, :required => true
|
44
|
+
def list_firewall_rules
|
45
|
+
try_with_rescue_in_session do
|
46
|
+
# call the api
|
47
|
+
rules = EnfApi::Firewall.instance.list_firewall_rules options[:network]
|
48
|
+
|
49
|
+
# display empty table and return
|
50
|
+
if rules.length == 0 then
|
51
|
+
display_firewall_rules rules
|
52
|
+
return
|
53
|
+
end
|
54
|
+
|
55
|
+
# sort the rules by direction, priority
|
56
|
+
sorted_rules = rules.sort{ |x,y|
|
57
|
+
r = x[:direction] <=> y[:direction]
|
58
|
+
if r == 0 then
|
59
|
+
x[:priority] <=> y[:priority]
|
60
|
+
else
|
61
|
+
r
|
62
|
+
end
|
63
|
+
}
|
64
|
+
|
65
|
+
# chunk them into egress/ingress arrays
|
66
|
+
egress_rules = Array.new
|
67
|
+
ingress_rules = Array.new
|
68
|
+
sorted_rules.each{ |rule|
|
69
|
+
if rule[:direction] == 'INGRESS' then
|
70
|
+
ingress_rules << rule
|
71
|
+
else
|
72
|
+
egress_rules << rule
|
73
|
+
end
|
74
|
+
}
|
75
|
+
|
76
|
+
# display data
|
77
|
+
if egress_rules.length > 0 then
|
78
|
+
say "Egress firewall rules(Endpoint -> ENF)", :yellow
|
79
|
+
display_firewall_rules egress_rules
|
80
|
+
|
81
|
+
# separate two tables
|
82
|
+
say ""
|
83
|
+
end
|
84
|
+
|
85
|
+
if ingress_rules.length > 0 then
|
86
|
+
say "Ingress firewall rules(ENF -> Endpoint)", :yellow
|
87
|
+
display_firewall_rules ingress_rules
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
desc "add-firewall-rule", "Add a firewall rule to a /64 network"
|
93
|
+
method_option :network, :type => :string, :required => true
|
94
|
+
method_option :priority, :type => :numeric, :required => true
|
95
|
+
method_option :protocol, :type => :string, :required => true, :enum => ['TCP', 'UDP', 'ICMP6', '6', '17', '58']
|
96
|
+
method_option :source_ip, :type => :string
|
97
|
+
method_option :source_port, :type => :numeric
|
98
|
+
method_option :dest_ip, :type => :string
|
99
|
+
method_option :dest_port, :type => :numeric
|
100
|
+
method_option :direction, :type => :string, :required => true, :enum => ['EGRESS', 'INGRESS']
|
101
|
+
method_option :action, :type => :string, :required => true, :enum => ['ACCEPT', 'DROP']
|
102
|
+
|
103
|
+
def add_firewall_rule
|
104
|
+
protocol_map = { 'TCP' => 'TCP', 'UDP' => 'UDP', 'ICMP6' => 'ICMP6', '6' => 'TCP', '17' => 'UDP', '58' => 'ICMP6' }
|
105
|
+
try_with_rescue_in_session do
|
106
|
+
# get options
|
107
|
+
rule = {
|
108
|
+
:ip_family => 'IP6',
|
109
|
+
:priority => options[:priority],
|
110
|
+
:protocol => protocol_map[ options[:protocol] ],
|
111
|
+
:source_ip => options[:source_ip] ? options[:source_ip] : '*',
|
112
|
+
:source_port => options[:source_port] ? options[:source_port] : 0,
|
113
|
+
:dest_ip => options[:dest_ip] ? options[:dest_ip] : '*',
|
114
|
+
:dest_port => options[:dest_port] ? options[:dest_port] : 0,
|
115
|
+
:direction => options[:direction],
|
116
|
+
:action => options[:action]
|
117
|
+
}
|
118
|
+
|
119
|
+
# call the api
|
120
|
+
EnfApi::Firewall.instance.add_firewall_rule options[:network], rule
|
121
|
+
|
122
|
+
# print success
|
123
|
+
say "Created firewall rule!", :green
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
desc "delete-firewall-rule", "Delete a firewall rule"
|
128
|
+
method_option :network, :type => :string, :required => true
|
129
|
+
method_option :id, :type => :string, :required => true
|
130
|
+
def delete_firewall_rule
|
131
|
+
try_with_rescue_in_session do
|
132
|
+
# call the api
|
133
|
+
EnfApi::Firewall.instance.delete_firewall_rules options[:network], options[:id]
|
134
|
+
|
135
|
+
# print success
|
136
|
+
say "Deleted firewall rule in #{options[:network]}!", :green
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# desc "delete-all-firewall-rules", "Delete a firewall rules in a /64 network"
|
141
|
+
# method_option :network, :type => :string, :required => true
|
142
|
+
# def delete_all_firewall_rules
|
143
|
+
# session = EnfCli::CTX.instance.session
|
144
|
+
# raise EnfCli::ERROR, "User Session not establised!" if !session
|
145
|
+
# EnfApi::Firewall.instance.delete_firewall_rules options[:network]
|
146
|
+
# end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
end
|