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.
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 'openssl'
17
- require 'enfapi'
18
- require 'enfthor'
19
- require 'readline'
20
- require 'singleton'
21
- require 'ipaddr'
22
-
23
- require 'rubygems/commands/update_command'
24
- require 'rubygems/commands/search_command'
25
-
26
-
27
- require 'enfcli/version'
28
- require 'enfcli/commands/xcr'
29
- require 'enfcli/commands/xiam'
30
- require 'enfcli/commands/xfw'
31
- require 'enfcli/commands/user'
32
- require 'enfcli/commands/captive'
33
- require 'enfcli/commands/xdns'
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 ipv6_bytes
67
- ip = IPAddr::new_ntoh( ipv6_bytes )
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 = 'Enter Password:' unless 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 'stty -echo'
117
+ system "stty -echo"
115
118
  password = $stdin.gets.chomp
116
- system 'stty echo'
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 'stty echo'
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([['CN', "#{ipv6}"]])
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 host=(value)
193
- @host = value
203
+ def auth_token
204
+ @session[:token]
194
205
  end
195
206
 
196
- def prompt
197
- "\001\033[1;32m\002#{@prompt}>\001\033[0m\002 "
207
+ def user
208
+ @user
198
209
  end
199
210
 
200
- def prompt=(value)
201
- if value
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 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, :required => true
227
- method_option :user, :type => :string, :required => true
228
- method_option :password, :type => :string
231
+ method_option :host, :type => :string
232
+ method_option :user, :type => :string
233
+
229
234
  def connect(*names)
230
- host = options[:host]
231
- user = options[: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
- # set session
245
- EnfCli::CTX.instance.session = resp[:data][0]
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 host, user
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 ['enfcli']
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(host, user)
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('INT') { system('stty', stty_save); exit }
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( dir )
334
-
335
- Dir.entries( dir ).each{ |f|
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( dir )
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