enfcli 3.3.2.pre.alpha
Sign up to get free protection for your applications and to get access to all the features.
- 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
|