enfcli 4.0.0 → 4.1.0.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 +4 -4
- data/.circleci/Dockerfile +2 -2
- data/.circleci/config.yml +5 -0
- data/Gemfile.lock +37 -25
- data/Makefile +7 -0
- data/README.md +52 -7
- data/enfcli.gemspec +28 -26
- data/format.sh +9 -0
- data/lib/enfapi.rb +86 -97
- data/lib/enfcli.rb +166 -94
- data/lib/enfcli/commands/captive.rb +149 -149
- data/lib/enfcli/commands/user.rb +23 -20
- data/lib/enfcli/commands/xcr.rb +95 -82
- data/lib/enfcli/commands/xdns.rb +53 -50
- data/lib/enfcli/commands/xfw.rb +37 -37
- data/lib/enfcli/commands/xiam.rb +87 -80
- data/lib/enfcli/version.rb +1 -1
- data/lib/enfthor.rb +38 -14
- metadata +62 -5
data/lib/enfcli.rb
CHANGED
@@ -13,26 +13,29 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
20
|
-
require
|
21
|
-
require
|
22
|
-
|
23
|
-
require
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
require
|
29
|
-
require
|
30
|
-
require
|
31
|
-
require
|
32
|
-
require
|
33
|
-
require
|
16
|
+
require "openssl"
|
17
|
+
require "enfapi"
|
18
|
+
require "enfthor"
|
19
|
+
require "readline"
|
20
|
+
require "singleton"
|
21
|
+
require "ipaddr"
|
22
|
+
require "clipboard"
|
23
|
+
require "json"
|
24
|
+
|
25
|
+
require "rubygems/commands/update_command"
|
26
|
+
require "rubygems/commands/search_command"
|
27
|
+
|
28
|
+
require "enfcli/version"
|
29
|
+
require "enfcli/commands/xcr"
|
30
|
+
require "enfcli/commands/xiam"
|
31
|
+
require "enfcli/commands/xfw"
|
32
|
+
require "enfcli/commands/user"
|
33
|
+
require "enfcli/commands/captive"
|
34
|
+
require "enfcli/commands/xdns"
|
34
35
|
|
35
36
|
module EnfCli
|
37
|
+
CONFIG_FILE = "#{Dir.home() + "/.xaptum_config.json"}"
|
38
|
+
|
36
39
|
FIREWALL_CMD = "firewall"
|
37
40
|
IAM_CMD = "iam"
|
38
41
|
NETWORK_CMD = "network"
|
@@ -63,13 +66,13 @@ module EnfCli
|
|
63
66
|
@ip.hton
|
64
67
|
end
|
65
68
|
|
66
|
-
def self.ntoh
|
67
|
-
ip = IPAddr::new_ntoh(
|
69
|
+
def self.ntoh(ipv6_bytes)
|
70
|
+
ip = IPAddr::new_ntoh(ipv6_bytes)
|
68
71
|
EnfCli::IPV6.new ip.to_s
|
69
72
|
end
|
70
73
|
|
71
74
|
private
|
72
|
-
|
75
|
+
|
73
76
|
attr_accessor :ip
|
74
77
|
end
|
75
78
|
|
@@ -84,10 +87,9 @@ module EnfCli
|
|
84
87
|
# store in prefix/len
|
85
88
|
@prefix = EnfCli::IPV6.new tokens[0]
|
86
89
|
@len = tokens[1].to_i
|
87
|
-
|
90
|
+
|
88
91
|
# raise if len is not 0
|
89
92
|
raise EnfCli::ERROR, "#{ipv6cidr} is not a valid CIDR notation." unless len > 2
|
90
|
-
|
91
93
|
end
|
92
94
|
|
93
95
|
def prefix_bytes
|
@@ -101,47 +103,47 @@ module EnfCli
|
|
101
103
|
def to_s
|
102
104
|
"#{@prefix.to_s}/#{@len}"
|
103
105
|
end
|
104
|
-
|
106
|
+
|
105
107
|
private
|
108
|
+
|
106
109
|
attr_accessor :prefix, :len
|
107
110
|
end
|
108
|
-
|
111
|
+
|
109
112
|
def self.ask_password(prompt = nil)
|
110
113
|
begin
|
111
|
-
prompt =
|
114
|
+
prompt = "Enter Password:" unless prompt
|
112
115
|
print prompt
|
113
116
|
# We hide the entered characters before to ask for the password
|
114
|
-
system
|
117
|
+
system "stty -echo"
|
115
118
|
password = $stdin.gets.chomp
|
116
|
-
system
|
119
|
+
system "stty echo"
|
117
120
|
puts ""
|
118
121
|
return password
|
119
|
-
|
120
122
|
rescue NoMethodError, Interrupt
|
121
123
|
# When the process is exited, we display the characters again
|
122
124
|
# And we exit
|
123
|
-
system
|
125
|
+
system "stty echo"
|
124
126
|
exit
|
125
127
|
end
|
126
128
|
end
|
127
129
|
|
128
130
|
def self.generate_ec_cert(key, ipv6)
|
129
|
-
# monkey patch
|
131
|
+
# monkey patch
|
130
132
|
OpenSSL::PKey::EC.send(:alias_method, :private?, :private_key?)
|
131
|
-
|
133
|
+
|
132
134
|
# Generate cert
|
133
135
|
cert = OpenSSL::X509::Certificate.new
|
134
|
-
cert.subject = cert.issuer = OpenSSL::X509::Name.new([[
|
136
|
+
cert.subject = cert.issuer = OpenSSL::X509::Name.new([["CN", "#{ipv6}"]])
|
135
137
|
cert.not_before = Time.now
|
136
138
|
cert.not_after = Time.now + 365 * 24 * 60 * 60
|
137
139
|
cert.public_key = key
|
138
140
|
cert.serial = 0x0
|
139
141
|
cert.version = 2
|
140
|
-
|
142
|
+
|
141
143
|
cert.sign key, OpenSSL::Digest::SHA1.new
|
142
144
|
cert
|
143
|
-
end
|
144
|
-
|
145
|
+
end
|
146
|
+
|
145
147
|
def self.expand_path(file)
|
146
148
|
new_file = File.expand_path(EnfCli::expand_env(file))
|
147
149
|
end
|
@@ -154,7 +156,7 @@ module EnfCli
|
|
154
156
|
ip = EnfCli::IPV6.new ipv6
|
155
157
|
ip.to_s
|
156
158
|
end
|
157
|
-
|
159
|
+
|
158
160
|
##
|
159
161
|
# EnfCli error
|
160
162
|
#
|
@@ -174,7 +176,16 @@ module EnfCli
|
|
174
176
|
|
175
177
|
def initialize
|
176
178
|
@prompt = "enfcli"
|
177
|
-
@host =
|
179
|
+
@host = ""
|
180
|
+
@user = ""
|
181
|
+
@session = nil
|
182
|
+
end
|
183
|
+
|
184
|
+
def init(host, user, session)
|
185
|
+
@host = host
|
186
|
+
@user = user
|
187
|
+
@session = session
|
188
|
+
@prompt = "enfcli-#{user}" if user
|
178
189
|
end
|
179
190
|
|
180
191
|
def xaptum_admin?
|
@@ -189,23 +200,17 @@ module EnfCli
|
|
189
200
|
"#{@host}"
|
190
201
|
end
|
191
202
|
|
192
|
-
def
|
193
|
-
@
|
203
|
+
def auth_token
|
204
|
+
@session[:token]
|
194
205
|
end
|
195
206
|
|
196
|
-
def
|
197
|
-
|
207
|
+
def user
|
208
|
+
@user
|
198
209
|
end
|
199
210
|
|
200
|
-
def prompt
|
201
|
-
|
202
|
-
@prompt = "enfcli-#{value}"
|
203
|
-
else
|
204
|
-
@prompt= "enfcli"
|
205
|
-
end
|
206
|
-
|
211
|
+
def prompt
|
212
|
+
"\001\033[1;32m\002#{@prompt}>\001\033[0m\002 "
|
207
213
|
end
|
208
|
-
|
209
214
|
end
|
210
215
|
|
211
216
|
##
|
@@ -213,75 +218,112 @@ module EnfCli
|
|
213
218
|
#
|
214
219
|
class CLI < EnfThor
|
215
220
|
no_commands {
|
216
|
-
def execute_gem_cmd
|
217
|
-
begin
|
221
|
+
def execute_gem_cmd(cmd)
|
222
|
+
begin
|
218
223
|
cmd.execute
|
219
224
|
rescue Gem::SystemExitException => e
|
220
225
|
say "Unable to execute commnad. Please try again!", :red
|
221
226
|
end
|
222
227
|
end
|
223
228
|
}
|
224
|
-
|
229
|
+
|
225
230
|
desc "connect", "Connect to ENF Controller"
|
226
|
-
method_option :host, :type => :string
|
227
|
-
method_option :user, :type => :string
|
228
|
-
|
231
|
+
method_option :host, :type => :string
|
232
|
+
method_option :user, :type => :string
|
233
|
+
|
229
234
|
def connect(*names)
|
230
|
-
host =
|
231
|
-
user =
|
235
|
+
host = ""
|
236
|
+
user = ""
|
232
237
|
|
233
238
|
try_with_rescue do
|
239
|
+
## first check for command options
|
240
|
+
if options[:host] && options[:user]
|
241
|
+
host = options[:host]
|
242
|
+
user = options[:user]
|
243
|
+
elsif File.file?(CONFIG_FILE) # then check for config file
|
244
|
+
config_json = JSON.load(File.open(CONFIG_FILE))
|
245
|
+
host = config_json["host"]
|
246
|
+
user = config_json["user"]
|
247
|
+
else
|
248
|
+
raise EnfCli::ERROR, "You must either specify the --host and --user parameters or create a Xaptum config file to connect."
|
249
|
+
end
|
250
|
+
|
234
251
|
# Make sure to use https as default
|
235
252
|
host = "https://#{host}" unless host =~ /^(http|https):\/\//
|
236
|
-
|
253
|
+
|
237
254
|
# Ask for password
|
238
255
|
say "Connecting to '#{host}'.....", :bold
|
239
256
|
password = EnfCli::ask_password()
|
240
|
-
|
257
|
+
|
241
258
|
# Authenticate
|
242
259
|
resp = EnfApi::API.instance.authenticate(host, user, password)
|
243
260
|
|
244
|
-
#
|
245
|
-
EnfCli::CTX.instance.
|
261
|
+
# initialize CTX
|
262
|
+
EnfCli::CTX.instance.init host, user, resp[:data][0]
|
246
263
|
|
247
264
|
# launch shell/exec cmd
|
248
265
|
if names.empty?
|
249
|
-
EnfCli::Shell::Console::start
|
266
|
+
EnfCli::Shell::Console::start
|
250
267
|
else
|
251
268
|
EnfCli::Shell::CLI.start names
|
252
269
|
end
|
253
270
|
end
|
254
|
-
end
|
271
|
+
end
|
255
272
|
|
256
273
|
map %w[--version -v] => :__print_version
|
257
274
|
desc "--version, -v", "print the version"
|
275
|
+
|
258
276
|
def __print_version
|
259
277
|
puts EnfCli::VERSION
|
260
278
|
end
|
261
279
|
|
262
280
|
desc "update", "", :hide => true
|
281
|
+
|
263
282
|
def update
|
264
283
|
cmd = Gem::Commands::UpdateCommand.new
|
265
|
-
cmd.handle_options [
|
284
|
+
cmd.handle_options ["enfcli"]
|
266
285
|
execute_gem_cmd cmd
|
267
286
|
end
|
268
287
|
|
269
288
|
desc "search", "", :hide => true
|
289
|
+
|
270
290
|
def search
|
271
291
|
cmd = Gem::Commands::SearchCommand.new
|
272
292
|
cmd.handle_options ["enfcli"]
|
273
293
|
execute_gem_cmd cmd
|
274
294
|
end
|
275
295
|
|
296
|
+
desc "create-config-file", "Create a Xaptum configuration file in your home directory"
|
297
|
+
method_option :host, :type => :string, :required => true
|
298
|
+
method_option :user, :type => :string, :required => true
|
299
|
+
|
300
|
+
def create_config_file
|
301
|
+
host = options[:host]
|
302
|
+
user = options[:user]
|
303
|
+
config_file = File.new(CONFIG_FILE, "w+")
|
304
|
+
config_file.puts({ :host => host, :user => user }.to_json)
|
305
|
+
config_file.close
|
306
|
+
say "Config file created successfully at #{CONFIG_FILE}!", :green
|
307
|
+
end
|
308
|
+
|
309
|
+
desc "display-config-file", "Displays your Xaptum configuraton file, if it exists"
|
310
|
+
|
311
|
+
def display_config_file
|
312
|
+
file = CONFIG_FILE
|
313
|
+
|
314
|
+
## return if file not found
|
315
|
+
raise EnfCli::ERROR, "#{file} not found!" unless File.exists?(file)
|
316
|
+
|
317
|
+
say File.readlines(file).join
|
318
|
+
end
|
319
|
+
|
276
320
|
default_task :connect
|
277
|
-
|
278
321
|
end
|
279
322
|
|
280
323
|
##
|
281
324
|
# Shell Module
|
282
325
|
#
|
283
326
|
module Shell
|
284
|
-
|
285
327
|
class Console
|
286
328
|
class << self
|
287
329
|
def execute(input)
|
@@ -289,61 +331,57 @@ module EnfCli
|
|
289
331
|
argv = input.split(/[\s=](?=(?:[^"]|"[^"]*")*$)/)
|
290
332
|
# now remove quotes.
|
291
333
|
argv.each do |arg|
|
292
|
-
arg.gsub!(/\A"|"\Z/,
|
334
|
+
arg.gsub!(/\A"|"\Z/, "")
|
293
335
|
end
|
294
336
|
EnfCli::Shell::CLI.start(argv)
|
295
337
|
end
|
296
338
|
|
297
|
-
def start
|
339
|
+
def start
|
298
340
|
$stdout.sync = true
|
299
|
-
# Set prompt
|
300
|
-
EnfCli::CTX.instance.prompt = user
|
301
341
|
|
302
|
-
# Set host
|
303
|
-
EnfCli::CTX.instance.host = host
|
304
|
-
|
305
342
|
# Read each line
|
306
|
-
comp = proc { |s| Readline::HISTORY.grep(/^#{Regexp.escape(s)}/) }
|
343
|
+
comp = proc { |s| Readline::HISTORY.grep(/^#{Regexp.escape(s)}/) }
|
307
344
|
Readline.completion_append_character = " "
|
308
345
|
Readline.completion_proc = comp
|
309
346
|
|
310
347
|
stty_save = `stty -g`.chomp
|
311
|
-
trap(
|
312
|
-
|
348
|
+
trap("INT") { system("stty", stty_save); exit }
|
349
|
+
|
313
350
|
while input = Readline.readline(EnfCli::CTX.instance.prompt, true)
|
314
351
|
break if input == "exit" or input == "\\q" or input == "quit"
|
315
|
-
|
352
|
+
|
316
353
|
# Remove blank lines from history
|
317
354
|
Readline::HISTORY.pop if input == ""
|
318
|
-
|
355
|
+
|
319
356
|
execute(input) unless input == ""
|
320
357
|
end
|
321
|
-
end
|
322
|
-
end
|
358
|
+
end
|
359
|
+
end
|
323
360
|
end
|
324
361
|
|
325
362
|
# Shell CLI class
|
326
|
-
class CLI < EnfThor
|
327
|
-
|
363
|
+
class CLI < EnfCli::EnfThor
|
328
364
|
desc "ls [<dir>]", "List files in a directory", :hide => true
|
329
365
|
method_option :dir, :type => :string, :required => false
|
366
|
+
|
330
367
|
def ls(dir = nil)
|
331
368
|
try_with_rescue do
|
332
369
|
dir = "." unless dir
|
333
|
-
dir = EnfCli::expand_path(
|
334
|
-
|
335
|
-
Dir.entries(
|
336
|
-
puts f unless f.start_with?(
|
370
|
+
dir = EnfCli::expand_path(dir)
|
371
|
+
|
372
|
+
Dir.entries(dir).each { |f|
|
373
|
+
puts f unless f.start_with?(".")
|
337
374
|
}
|
338
375
|
end
|
339
376
|
end
|
340
377
|
|
341
378
|
desc "cat <file>", "Display contents of a file", :hide => true
|
379
|
+
|
342
380
|
def cat(file)
|
343
381
|
try_with_rescue do
|
344
382
|
# expand path
|
345
383
|
file = EnfCli::expand_path(file)
|
346
|
-
|
384
|
+
|
347
385
|
## return if keyfile not found
|
348
386
|
raise EnfCli::ERROR, "#{file} not found!" unless File.exists?(file)
|
349
387
|
|
@@ -352,6 +390,7 @@ module EnfCli
|
|
352
390
|
end
|
353
391
|
|
354
392
|
desc "pwd", "Current Working Directory", :hide => true
|
393
|
+
|
355
394
|
def pwd
|
356
395
|
try_with_rescue do
|
357
396
|
say Dir.pwd
|
@@ -359,35 +398,69 @@ module EnfCli
|
|
359
398
|
end
|
360
399
|
|
361
400
|
desc "cd [<dir>]", "Change working directory", :hide => true
|
401
|
+
|
362
402
|
def cd(dir = "~")
|
363
403
|
try_with_rescue do
|
364
|
-
dir = EnfCli::expand_path(
|
404
|
+
dir = EnfCli::expand_path(dir)
|
365
405
|
raise EnfCli::ERROR, "No such directory #{dir}" unless Dir.exist?(dir)
|
366
406
|
Dir.chdir(dir)
|
367
407
|
end
|
368
408
|
end
|
369
409
|
|
370
410
|
desc "host", "Display ENF Controller host", :hide => true
|
411
|
+
|
371
412
|
def host
|
372
413
|
try_with_rescue do
|
373
414
|
say EnfCli::CTX.instance.host, :bold
|
374
415
|
end
|
375
416
|
end
|
376
|
-
|
417
|
+
|
377
418
|
desc "clear", "Clear Terminal Screen", :hide => true
|
419
|
+
|
378
420
|
def clear
|
379
421
|
try_with_rescue do
|
380
422
|
clear_code = %x{clear}
|
381
423
|
print clear_code or system("cls")
|
382
424
|
end
|
383
425
|
end
|
384
|
-
|
426
|
+
|
427
|
+
desc "display-session-token", "Gets the current session token"
|
428
|
+
|
429
|
+
def display_session_token
|
430
|
+
try_with_rescue_in_session do
|
431
|
+
say "#{EnfCli::CTX.instance.auth_token}"
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
desc "refresh-session-token", "Refreshes the current session token"
|
436
|
+
|
437
|
+
def refresh_session_token
|
438
|
+
try_with_rescue_in_session do
|
439
|
+
# Get user and host
|
440
|
+
host = EnfCli::CTX.instance.host
|
441
|
+
user = EnfCli::CTX.instance.user
|
442
|
+
|
443
|
+
# Ask for password
|
444
|
+
say "Refreshing session token.....", :bold
|
445
|
+
password = EnfCli::ask_password()
|
446
|
+
|
447
|
+
# Authenticate
|
448
|
+
resp = EnfApi::API.instance.authenticate(host, user, password)
|
449
|
+
|
450
|
+
# update session
|
451
|
+
EnfCli::CTX.instance.session = resp[:data][0]
|
452
|
+
|
453
|
+
# display success
|
454
|
+
say "Refreshed session token!", :green
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
385
458
|
desc "#{EnfCli::NETWORK_CMD} COMMANDS", "#{EnfCli::NETWORK_CMD} commands"
|
386
459
|
subcommand EnfCli::NETWORK_CMD, EnfCli::Cmd::Xcr
|
387
|
-
|
460
|
+
|
388
461
|
desc "#{EnfCli::IAM_CMD} COMMANDS", "#{EnfCli::IAM_CMD} commands"
|
389
462
|
subcommand EnfCli::IAM_CMD, EnfCli::Cmd::Xiam
|
390
|
-
|
463
|
+
|
391
464
|
desc "#{EnfCli::FIREWALL_CMD} COMMANDS", "#{EnfCli::FIREWALL_CMD} commands"
|
392
465
|
subcommand EnfCli::FIREWALL_CMD, EnfCli::Cmd::Xfw
|
393
466
|
|
@@ -401,5 +474,4 @@ module EnfCli
|
|
401
474
|
subcommand EnfCli::DNS_CMD, EnfCli::Cmd::Xdns
|
402
475
|
end
|
403
476
|
end
|
404
|
-
|
405
477
|
end
|