summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSaku Ytti <saku@ytti.fi>2014-04-14 16:28:23 +0300
committerSaku Ytti <saku@ytti.fi>2014-04-14 16:28:23 +0300
commit57a8f4bc04b4f87ad0d7028dcbf29b96d49eaffd (patch)
tree82567c791b0114e62fa3b978eb2bb95733d6488b /lib
parent1a1794b2b3ac99764852546c550fd7988f84c37b (diff)
Use 'asetus' for configuration files
Main benefits a) we get support for system wide configs b) we don't use symbols in config file, they're confusing to non-rubyist
Diffstat (limited to 'lib')
-rw-r--r--lib/oxidized/cli.rb48
-rw-r--r--lib/oxidized/config.rb44
-rw-r--r--lib/oxidized/config/bootstrap.rb33
-rw-r--r--lib/oxidized/config/core.rb33
-rw-r--r--lib/oxidized/config/defaults.rb14
-rw-r--r--lib/oxidized/core.rb2
-rw-r--r--lib/oxidized/input/ssh.rb14
-rw-r--r--lib/oxidized/input/telnet.rb2
-rw-r--r--lib/oxidized/node.rb4
-rw-r--r--lib/oxidized/nodes.rb2
-rw-r--r--lib/oxidized/output/file.rb15
-rw-r--r--lib/oxidized/output/git.rb23
-rw-r--r--lib/oxidized/output/output.rb1
-rw-r--r--lib/oxidized/source/csv.rb27
-rw-r--r--lib/oxidized/source/source.rb1
-rw-r--r--lib/oxidized/source/sql.rb29
16 files changed, 149 insertions, 143 deletions
diff --git a/lib/oxidized/cli.rb b/lib/oxidized/cli.rb
new file mode 100644
index 0000000..720f405
--- /dev/null
+++ b/lib/oxidized/cli.rb
@@ -0,0 +1,48 @@
+module Oxidized
+ class CLI
+ require 'oxidized'
+ require 'slop'
+ class CLIError < OxidizedError; end
+ class NoConfig < CLIError; end
+
+ def run
+ Process.daemon unless CFG.debug
+ begin
+ Oxidized.new
+ rescue => error
+ crash error
+ raise
+ end
+ end
+
+ private
+
+ def initialize
+ if CFGS.system.empty? and CFGS.user.empty?
+ CFGS.user = CFGS.default
+ CFGS.save :user
+ raise NoConfig, 'edit ~/.config/oxidized/config'
+ end
+ _args, opts = parse_opts
+ CFG.debug = true if opts[:debug]
+ end
+
+ def crash error
+ open Config::Crash, 'w' do |file|
+ file.puts '-' * 50
+ file.puts Time.now.utc
+ file.puts error.message + ' [' + error.class.to_s + ']'
+ file.puts '-' * 50
+ file.puts error.backtrace
+ file.puts '-' * 50
+ end
+ end
+
+ def parse_opts
+ opts = Slop.new(:help=>true) do
+ on 'd', 'debug', 'turn on debugging'
+ end
+ [opts.parse!, opts]
+ end
+ end
+end
diff --git a/lib/oxidized/config.rb b/lib/oxidized/config.rb
new file mode 100644
index 0000000..475ae14
--- /dev/null
+++ b/lib/oxidized/config.rb
@@ -0,0 +1,44 @@
+module Oxidized
+ require 'asetus'
+ class Config
+ Root = File.join ENV['HOME'], '.config', 'oxidized'
+ Crash = File.join Root, 'crash'
+ InputDir = File.join Directory, %w(lib oxidized input)
+ OutputDir = File.join Directory, %w(lib oxidized output)
+ ModelDir = File.join Directory, %w(lib oxidized model)
+ SourceDir = File.join Directory, %w(lib oxidized source)
+ Sleep = 1
+ end
+ class << self
+ attr_accessor :mgr
+ end
+ CFGS = Asetus.new :name=>'oxidized', :load=>false, :key_to_s=>true
+ CFGS.default.username = 'username'
+ CFGS.default.password = 'password'
+ CFGS.default.model = 'junos'
+ CFGS.default.interval = 3600
+ CFGS.default.log = File.join Config::Root, 'log'
+ CFGS.default.debug = false
+ CFGS.default.threads = 30
+ CFGS.default.timeout = 30
+ CFGS.default.prompt = /^([\w.@-]+[#>]\s?)$/
+ CFGS.default.rest = '0.0.0.0:8888' # or false to disable
+ CFGS.default.vars = {} # could be 'enable'=>'enablePW'
+
+ CFGS.default.input.default = 'ssh, telnet'
+ CFGS.default.input.ssh.secure = false
+
+ CFGS.default.output.default = 'git'
+ CFGS.default.source.default = 'csv'
+
+ CFGS.default.model_map = {
+ 'cisco' => 'ios',
+ 'juniper' => 'junos',
+ }
+
+ CFGS.load # load system+user configs, merge to Config.cfg
+ CFG = CFGS.cfg # convenienence, instead of Config.cfg.password, CFG.password
+
+ Log.level = Logger::INFO unless CFG.debug
+ Log.file = CFG.log if CFG.log
+end
diff --git a/lib/oxidized/config/bootstrap.rb b/lib/oxidized/config/bootstrap.rb
deleted file mode 100644
index 008d88a..0000000
--- a/lib/oxidized/config/bootstrap.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-module Oxidized
- require 'fileutils'
- FileUtils.mkdir_p Config::Root
- CFG.username = 'username'
- CFG.password = 'password'
- CFG.model = 'junos'
- CFG.interval = 3600
- CFG.log = File.join Config::Root, 'log'
- CFG.debug = false
- CFG.threads = 30
- CFG.timeout = 30
- CFG.prompt = /^([\w.@-]+[#>]\s?)$/
- CFG.rest = '0.0.0.0:8888'
- CFG.vars = {
- #:enable => 'enablePW',
- }
- CFG.input = {
- :default => 'ssh, telnet',
- :ssh => {
- :secure => false,
- }
- }
- CFG.output = {
- :default => 'git',
- }
- CFG.source = {
- :default => 'csv',
- }
- CFG.model_map = {
- 'cisco' => 'ios',
- 'juniper' => 'junos',
- }
-end
diff --git a/lib/oxidized/config/core.rb b/lib/oxidized/config/core.rb
deleted file mode 100644
index 59ada3a..0000000
--- a/lib/oxidized/config/core.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-module Oxidized
- require 'ostruct'
- require 'yaml'
- class Config < OpenStruct
- require 'oxidized/config/defaults'
- # @param file [string] configuration file location
- def initialize file=File.join(Config::Root, 'config')
- super()
- @file = file.to_s
- end
- # load config from file or bootstrap with built-ins
- def load
- if File.exists? @file
- cfg = YAML.load_file @file
- marshal_load marshal_dump.merge(cfg)
- else
- save
- end
- end
- def defaults
- require 'oxidized/config/bootstrap'
- end
- # save config to file
- def save
- File.write @file, YAML.dump(marshal_dump)
- end
- end
- CFG = Config.new
- CFG.defaults
- CFG.load
- Log.level = Logger::INFO unless CFG.debug
- Log.file = CFG.log if CFG.log
-end
diff --git a/lib/oxidized/config/defaults.rb b/lib/oxidized/config/defaults.rb
deleted file mode 100644
index c30143f..0000000
--- a/lib/oxidized/config/defaults.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-module Oxidized
- class Config
- Root = File.join ENV['HOME'], '.config', 'oxidized'
- Crash = File.join Root, 'crash'
- InputDir = File.join Directory, %w(lib oxidized input)
- OutputDir = File.join Directory, %w(lib oxidized output)
- ModelDir = File.join Directory, %w(lib oxidized model)
- SourceDir = File.join Directory, %w(lib oxidized source)
- Sleep = 1
- end
- class << self
- attr_accessor :mgr
- end
-end
diff --git a/lib/oxidized/core.rb b/lib/oxidized/core.rb
index 14de9ab..3c728b6 100644
--- a/lib/oxidized/core.rb
+++ b/lib/oxidized/core.rb
@@ -1,6 +1,6 @@
module Oxidized
require 'oxidized/log'
- require 'oxidized/config/core'
+ require 'oxidized/config'
require 'oxidized/worker'
require 'oxidized/nodes'
require 'oxidized/manager'
diff --git a/lib/oxidized/input/ssh.rb b/lib/oxidized/input/ssh.rb
index dae1d74..570f8a8 100644
--- a/lib/oxidized/input/ssh.rb
+++ b/lib/oxidized/input/ssh.rb
@@ -12,14 +12,14 @@ module Oxidized
Net::SSH::AuthenticationFailed,
],
}
- include CLI
+ include Input::CLI
class NoShell < OxidizedError; end
def connect node
@node = node
@output = ''
@node.model.cfg['ssh'].each { |cb| instance_exec(&cb) }
- secure = CFG.input[:ssh][:secure]
+ secure = CFG.input.ssh.secure
@ssh = Net::SSH.start @node.ip, @node.auth[:username],
:password => @node.auth[:password], :timeout => CFG.timeout,
:paranoid => secure
@@ -64,14 +64,14 @@ module Oxidized
def shell_open ssh
@ses = ssh.open_channel do |ch|
- ch.on_data do |ch, data|
+ ch.on_data do |_ch, data|
@output << data
@output = @node.model.expects @output
end
- ch.request_pty do |ch, success|
- raise NoShell, "Can't get PTY" unless success
- ch.send_channel_request 'shell' do |ch, success|
- raise NoShell, "Can't get shell" unless success
+ ch.request_pty do |_ch, success_pty|
+ raise NoShell, "Can't get PTY" unless success_pty
+ ch.send_channel_request 'shell' do |_ch, success_shell|
+ raise NoShell, "Can't get shell" unless success_shell
end
end
end
diff --git a/lib/oxidized/input/telnet.rb b/lib/oxidized/input/telnet.rb
index 4e80ceb..218b13c 100644
--- a/lib/oxidized/input/telnet.rb
+++ b/lib/oxidized/input/telnet.rb
@@ -3,7 +3,7 @@ module Oxidized
require 'oxidized/input/cli'
class Telnet < Input
RescueFail = {}
- include CLI
+ include Input::CLI
attr_reader :telnet
def connect node
diff --git a/lib/oxidized/node.rb b/lib/oxidized/node.rb
index 0cb5cb3..3ac1c90 100644
--- a/lib/oxidized/node.rb
+++ b/lib/oxidized/node.rb
@@ -106,7 +106,7 @@ module Oxidized
end
def resolve_input opt
- inputs = (opt[:input] or CFG.input[:default])
+ inputs = (opt[:input] or CFG.input.default)
inputs.split(/\s*,\s*/).map do |input|
if not Oxidized.mgr.input[input]
Oxidized.mgr.add_input input or raise MethodNotFound, "#{input} not found for node #{ip}"
@@ -116,7 +116,7 @@ module Oxidized
end
def resolve_output opt
- output = (opt[:output] or CFG.output[:default])
+ output = (opt[:output] or CFG.output.default)
if not Oxidized.mgr.output[output]
Oxidized.mgr.add_output output or raise MethodNotFound, "#{output} not found for node #{ip}"
end
diff --git a/lib/oxidized/nodes.rb b/lib/oxidized/nodes.rb
index 8dadaef..213f534 100644
--- a/lib/oxidized/nodes.rb
+++ b/lib/oxidized/nodes.rb
@@ -10,7 +10,7 @@ module Oxidized
with_lock do
new = []
node_want_ip = (IPAddr.new(node_want) rescue nil) if node_want
- @source = CFG.source[:default]
+ @source = CFG.source.default
Oxidized.mgr.add_source @source
Oxidized.mgr.source[@source].new.load.each do |node|
diff --git a/lib/oxidized/output/file.rb b/lib/oxidized/output/file.rb
index ee8a9a6..f3443b4 100644
--- a/lib/oxidized/output/file.rb
+++ b/lib/oxidized/output/file.rb
@@ -3,20 +3,19 @@ class OxFile < Output
require 'fileutils'
def initialize
- @cfg = CFG.output[:file]
+ @cfg = CFG.output.file
end
def setup
- if not @cfg
- CFG.output[:file] = {
- :directory => File.join(Config::Root, 'configs')
- }
- CFG.save
+ if @cfg.empty?
+ CFGS.user.output.file.directory = File.join(Config::Root, 'configs')
+ CFGS.save :user
+ raise NoConfig, 'no output file config, edit ~/.config/oxidized/config'
end
end
def store node, data, opt={}
- file = @cfg[:directory]
+ file = @cfg.directory
if opt[:group]
file = File.join File.dirname(file), opt[:group]
end
@@ -26,7 +25,7 @@ class OxFile < Output
end
def fetch node, group
- cfg_dir = @cfg[:directory]
+ cfg_dir = @cfg.directory
if group # group is explicitly defined by user
IO.readlines File.join(cfg_dir, group, node)
else
diff --git a/lib/oxidized/output/git.rb b/lib/oxidized/output/git.rb
index b4fa4a8..ff9237b 100644
--- a/lib/oxidized/output/git.rb
+++ b/lib/oxidized/output/git.rb
@@ -5,25 +5,24 @@ class Git < Output
include Grit
def initialize
- @cfg = CFG.output[:git]
+ @cfg = CFG.output.git
end
def setup
- if not @cfg
- CFG.output[:git] = {
- :user => 'Oxidized',
- :email => 'o@example.com',
- :repo => File.join(Config::Root, 'oxidized.git')
- }
- CFG.save
+ if @cfg.empty?
+ CFGS.user.output.git.user = 'Oxidized'
+ CFGS.user.output.git.email = 'o@example.com'
+ CFGS.user.output.git.repo = File.join(Config::Root, 'oxidized.git')
+ CFGS.save :user
+ raise NoConfig, 'no output git config, edit ~/.config/oxidized/config'
end
end
def store file, data, opt={}
msg = opt[:msg]
- user = (opt[:user] or @cfg[:user])
- email = (opt[:email] or @cfg[:email])
- repo = @cfg[:repo]
+ user = (opt[:user] or @cfg.user)
+ email = (opt[:email] or @cfg.email)
+ repo = @cfg.repo
if opt[:group]
repo = File.join File.dirname(repo), opt[:group] + '.git'
end
@@ -41,7 +40,7 @@ class Git < Output
def fetch node, group
begin
- repo = Repo.new(@cfg[:repo])
+ repo = Repo.new(@cfg.repo)
(repo.tree / node).data
rescue
'node not found'
diff --git a/lib/oxidized/output/output.rb b/lib/oxidized/output/output.rb
index 61cb2b5..54d616c 100644
--- a/lib/oxidized/output/output.rb
+++ b/lib/oxidized/output/output.rb
@@ -1,5 +1,6 @@
module Oxidized
class Output
+ class NoConfig < OxidizedError; end
class << self
def inherited klass
Oxidized.mgr.loader = { :class => klass }
diff --git a/lib/oxidized/source/csv.rb b/lib/oxidized/source/csv.rb
index cf73fc8..9d291c7 100644
--- a/lib/oxidized/source/csv.rb
+++ b/lib/oxidized/source/csv.rb
@@ -1,31 +1,28 @@
module Oxidized
class CSV < Source
def initialize
- @cfg = CFG.source[:csv]
+ @cfg = CFG.source.csv
super
end
def setup
- if not @cfg
- CFG.source[:csv] = {
- :file => File.join(Config::Root, 'router.db'),
- :delimiter => /:/,
- :map => {
- :name => 0,
- :model => 1,
- }
- }
- CFG.save
+ if @cfg.empty?
+ CFGS.user.source.csv.file = File.join(Config::Root, 'router.db')
+ CFGS.user.source.csv.delimiter = /:/
+ CFGS.user.source.csv.map.name = 0
+ CFGS.user.source.csv.map.model = 1
+ CFGS.save :user
+ raise NoConfig, 'no source csv config, edit ~/.config/oxidized/config'
end
end
def load
nodes = []
- open(@cfg[:file]).each_line do |line|
- data = line.chomp.split @cfg[:delimiter]
+ open(@cfg.file).each_line do |line|
+ data = line.chomp.split @cfg.delimiter
keys = {}
- @cfg[:map].each do |key, position|
- keys[key] = data[position]
+ @cfg.map.each do |key, position|
+ keys[key.to_sym] = data[position]
end
keys[:model] = map_model keys[:model] if keys.key? :model
nodes << keys
diff --git a/lib/oxidized/source/source.rb b/lib/oxidized/source/source.rb
index f5976a0..93c9b6f 100644
--- a/lib/oxidized/source/source.rb
+++ b/lib/oxidized/source/source.rb
@@ -1,5 +1,6 @@
module Oxidized
class Source
+ class NoConfig < OxidizedError; end
class << self
def inherited klass
Oxidized.mgr.loader = { :class => klass }
diff --git a/lib/oxidized/source/sql.rb b/lib/oxidized/source/sql.rb
index 385f632..f84a7a8 100644
--- a/lib/oxidized/source/sql.rb
+++ b/lib/oxidized/source/sql.rb
@@ -4,34 +4,31 @@ class SQL < Source
def initialize
super
- @cfg = CFG.source[:sql]
+ @cfg = CFG.source.sql
end
def setup
- if not @cfg
- CFG.source[:sql] = {
- :adapter => 'sqlite',
- :file => File.join(Config::Root, 'sqlite.db'),
- :table => 'devices',
- :map => {
- :name => 'name',
- :model => 'rancid',
- }
- }
- CFG.save
+ if @cfg.empty?
+ CFGS.user.source.sql.adapter = 'sqlite'
+ CFGS.user.source.sql.file = File.join(Config::Root, 'sqlite.db')
+ CFGS.user.source.sql.table = 'devices'
+ CFGS.user.source.sql.map.name = 'name'
+ CFGS.user.source.sql.map.model = 'rancid'
+ CFGS.save :user
+ raise NoConfig, 'no source sql config, edit ~/.config/oxidized/config'
end
end
def load
nodes = []
- db = case @cfg[:adapter]
+ db = case @cfg.adapter
when 'sqlite'
require 'sqlite3'
- Sequel.sqlite @cfg[:file]
+ Sequel.sqlite @cfg.file
end
- db[@cfg[:table].to_sym].each do |node|
+ db[@cfg.table.to_sym].each do |node|
keys = {}
- @cfg[:map].each { |key, sql_column| keys[key] = node[sql_column.to_sym] }
+ @cfg.map.each { |key, sql_column| keys[key.to_sym] = node[sql_column.to_sym] }
keys[:model] = map_model keys[:model] if keys.key? :model
nodes << keys
end