lib/openvpn-status-web.rb in openvpn-status-web-0.0.1 vs lib/openvpn-status-web.rb in openvpn-status-web-1.0.0

- old
+ new

@@ -1,14 +1,21 @@ #!/usr/bin/env ruby +require 'date' require 'etc' require 'logger' require 'ipaddr' require 'yaml' require 'rack' +require 'erb' require 'metriks' +require 'better_errors' +require 'openvpn-status-web/status' +require 'openvpn-status-web/parser/v1' +require 'openvpn-status-web/parser/v2' +require 'openvpn-status-web/parser/v3' require 'openvpn-status-web/int_patch' require 'openvpn-status-web/version' module OpenVPNStatusWeb def self.logger @@ -24,73 +31,97 @@ "[%s] %-5s %s\n" % [Time.now.strftime('%Y-%m-%d %H:%M:%S'), lvl, msg.to_s] end end class Daemon - def initialize(name, file) - @name = name - @file = file + def initialize(vpns) + @vpns = vpns + + @main_tmpl = read_template(File.join(File.dirname(__FILE__), 'openvpn-status-web/main.html.erb')) end def call(env) - main_tmpl = read_template(File.join(File.dirname(__FILE__), 'openvpn-status-web/main.html.erb')) + return [405, {"Content-Type" => "text/plain"}, ["Method Not Allowed"]] if env["REQUEST_METHOD"] != "GET" + return [404, {"Content-Type" => "text/plain"}, ["Not Found"]] if env["PATH_INFO"] != "/" + # variables for template - name = @name - client_list, routing_table, global_stats = read_status_log(@file) - - html = main_tmpl.result(binding) + vpns = @vpns + stati = {} + @vpns.each do |name,config| + stati[name] = parse_status_log(config) + end + # eval + html = @main_tmpl.result(binding) + [200, {"Content-Type" => "text/html"}, [html]] end def read_template(file) text = File.open(file, 'rb') do |f| f.read end ERB.new(text) end - def read_status_log(file) - text = File.open(file, 'rb') do |f| f.read end + def parse_status_log(vpn) + text = File.open(vpn['status_file'], 'rb') do |f| f.read end - current_section = :none - client_list = [] - routing_table = [] - global_stats = [] - - text.lines.each do |line| - (current_section = :cl; next) if line == "OpenVPN CLIENT LIST\n" - (current_section = :rt; next) if line == "ROUTING TABLE\n" - (current_section = :gs; next) if line == "GLOBAL STATS\n" - (current_section = :end; next) if line == "END\n" - - case current_section - when :cl then client_list << line.strip.split(',') - when :rt then routing_table << line.strip.split(',') - when :gs then global_stats << line.strip.split(',') - end + case vpn['version'] + when 1 + OpenVPNStatusWeb::Parser::V1.new.parse_status_log(text) + when 2 + OpenVPNStatusWeb::Parser::V2.new.parse_status_log(text) + when 3 + OpenVPNStatusWeb::Parser::V3.new.parse_status_log(text) + else + raise "No suitable parser for status-version #{vpn['version']}" end - - [client_list[2..-1], routing_table[1..-1], global_stats] end def self.run! - if ARGV.length != 4 - puts "Usage: openvpn-status-web vpn-name status-log listen-host listen-port" + if ARGV.length != 1 + puts "Usage: openvpn-status-web config_file" exit 1 end - OpenVPNStatusWeb.logger = Logger.new(STDOUT) + config_file = ARGV[0] + if not File.file?(config_file) + puts "Config file not found!" + exit 1 + end + + puts "openvpn-status-web version #{OpenVPNStatusWeb::VERSION}" + puts "Using config file #{config_file}" + + config = YAML::load(File.open(config_file, 'r') { |f| f.read }) + + if config['logfile'] + OpenVPNStatusWeb.logger = Logger.new(config['logfile']) + else + OpenVPNStatusWeb.logger = Logger.new(STDOUT) + end + OpenVPNStatusWeb.logger.progname = "openvpn-status-web" OpenVPNStatusWeb.logger.formatter = LogFormatter.new OpenVPNStatusWeb.logger.info "Starting..." + # drop privs (first change group than user) + Process::Sys.setgid(Etc.getgrnam(config['group']).gid) if config['group'] + Process::Sys.setuid(Etc.getpwnam(config['user']).uid) if config['user'] + + # configure rack + app = Daemon.new(config['vpns']) + if ENV['RACK_ENV'] == "development" + app = BetterErrors::Middleware.new(app) + BetterErrors.application_root = File.expand_path("..", __FILE__) + end + Signal.trap('INT') do OpenVPNStatusWeb.logger.info "Quitting..." Rack::Handler::WEBrick.shutdown end - - app = Daemon.new(ARGV[0], ARGV[1]) - Rack::Handler::WEBrick.run app, :Host => ARGV[2], :Port => ARGV[3] + + Rack::Handler::WEBrick.run app, :Host => config['host'], :Port => config['port'] end end end