diff options
-rw-r--r-- | .travis.yml | 2 | ||||
-rw-r--r-- | Gemfile.lock | 2 | ||||
-rw-r--r-- | README.md | 20 | ||||
-rwxr-xr-x | extra/oxidized.init.d | 87 | ||||
-rw-r--r-- | lib/oxidized.rb | 1 | ||||
-rw-r--r-- | lib/oxidized/cli.rb | 4 | ||||
-rw-r--r-- | lib/oxidized/config.rb | 4 | ||||
-rw-r--r-- | lib/oxidized/input/ssh.rb | 18 | ||||
-rw-r--r-- | lib/oxidized/model/airos.rb | 2 | ||||
-rw-r--r-- | lib/oxidized/model/fortios.rb | 5 | ||||
-rw-r--r-- | lib/oxidized/model/ipos.rb | 37 | ||||
-rw-r--r-- | lib/oxidized/model/junos.rb | 2 | ||||
-rw-r--r-- | lib/oxidized/model/mtrlrfs.rb | 37 | ||||
-rw-r--r-- | lib/oxidized/model/xos.rb | 6 | ||||
-rw-r--r-- | spec/cli_spec.rb | 25 |
15 files changed, 240 insertions, 12 deletions
diff --git a/.travis.yml b/.travis.yml index 3734051..8f97b30 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,5 @@ language: ruby +sudo: false +cache: bundler rvm: - 2.1.6 diff --git a/Gemfile.lock b/Gemfile.lock index 8d19651..6be5978 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - oxidized (0.11.0) + oxidized (0.12.2) asetus (~> 0.1) net-ssh (~> 3.0, >= 3.0.2) rugged (~> 0.21, >= 0.21.4) @@ -76,8 +76,11 @@ Oxidized is a network device configuration backup tool. It's a RANCID replacemen * DELL * PowerConnect * AOSW + * Ericsson/Redback + * IPOS (former SEOS) * Extreme Networks * XOS + * WM * F5 * TMOS * Force10 @@ -95,6 +98,8 @@ Oxidized is a network device configuration backup tool. It's a RANCID replacemen * ScreenOS (Netscreen) * Mikrotik * RouterOS + * Motorola + * RFS * MRV * MasterOS * Opengear @@ -137,6 +142,21 @@ Oxidized configuration is in YAML format. Configuration files are subsequently s To initialize a default configuration in your home directory ```~/.config/oxidized/config```, simply run ```oxidized``` once. If you don't further configure anything from the output and source sections, it'll extend the examples on a subsequent ```oxidized``` execution. This is useful to see what options for a specific source or output backend are available. +You can set the env variable `OXIDIZED_HOME` to change its home directory. + +``` +OXIDIZED_HOME=/etc/oxidized + +$ tree -L 1 /etc/oxidized +/etc/oxidized/ +├── config +├── log-router-ssh +├── log-router-telnet +├── pid +├── router.db +└── repository.git +``` + ## Source Oxidized supports ```CSV```, ```SQLite``` and ```HTTP``` as source backends. The CSV backend reads nodes from a rancid compatible router.db file. The SQLite backend will fire queries against a database and map certain fields to model items. The HTTP backend will fire queries against a http/https url. Take a look at the [Cookbook](#cookbook) for more details. diff --git a/extra/oxidized.init.d b/extra/oxidized.init.d new file mode 100755 index 0000000..d2fdf00 --- /dev/null +++ b/extra/oxidized.init.d @@ -0,0 +1,87 @@ +#!/bin/sh +# chkconfig: - 99 01 +# description: Oxidized - Network Device Configuration Backup Tool +# processname: /opt/ruby-2.1/bin/oxidized + +# Source function library +. /etc/rc.d/init.d/functions + +name="oxidized" +desc="Oxidized" +cmd=oxidized +args="--daemonize" +lockfile=/var/lock/subsys/$name +pidfile=/etc/oxidized/pid + +export OXIDIZED_HOME=/etc/oxidized + +# Source sysconfig configuration +[ -r /etc/sysconfig/$name ] && . /etc/sysconfig/$name + +start() { + echo -n $"Starting $desc: " + daemon ${cmd} ${args} + retval=$? + if [ $retval = 0 ] + then + echo_success + touch $lockfile + else + echo_failure + fi + echo + return $retval +} + +stop() { + echo -n $"Stopping $desc: " + killproc -p $pidfile + retval=$? + [ $retval -eq 0 ] && rm -f $lockfile + rm -f $pidfile + echo + return $retval +} + +restart() { + stop + start +} + +reload() { + echo -n $"Reloading config..." + curl -s http://localhost:8888/reload?format=json -O /dev/null + echo +} + +rh_status() { + status -p $pidfile $cmd +} + +rh_status_q() { + rh_status >/dev/null 2>&1 +} + +case "$1" in + start) + rh_status_q && exit 0 + $1 + ;; + stop) + rh_status_q || exit 0 + $1 + ;; + restart) + $1 + ;; + reload) + rh_status_q || exit 0 + $1 + ;; + status) + rh_status + ;; + *) + echo $"Usage: $0 {start|stop|restart|reload|status}" + exit 2 +esac diff --git a/lib/oxidized.rb b/lib/oxidized.rb index e92224a..dfd9679 100644 --- a/lib/oxidized.rb +++ b/lib/oxidized.rb @@ -3,6 +3,7 @@ module Oxidized Directory = File.expand_path(File.join(File.dirname(__FILE__), '../')) + require 'oxidized/version' require 'oxidized/string' require 'oxidized/config' require 'oxidized/config/vars' diff --git a/lib/oxidized/cli.rb b/lib/oxidized/cli.rb index d35eab3..0594dcb 100644 --- a/lib/oxidized/cli.rb +++ b/lib/oxidized/cli.rb @@ -43,6 +43,10 @@ module Oxidized opts = Slop.new(:help=>true) do on 'd', 'debug', 'turn on debugging' on 'daemonize', 'Daemonize/fork the process' + on 'v', 'version', 'show version' do + puts Oxidized::VERSION + Kernel.exit + end end [opts.parse!, opts] end diff --git a/lib/oxidized/config.rb b/lib/oxidized/config.rb index d2d12d8..7884625 100644 --- a/lib/oxidized/config.rb +++ b/lib/oxidized/config.rb @@ -3,7 +3,7 @@ module Oxidized class NoConfig < OxidizedError; end class InvalidConfig < OxidizedError; end class Config - Root = File.join ENV['HOME'], '.config', 'oxidized' + Root = ENV['OXIDIZED_HOME'] || File.join(ENV['HOME'], '.config', 'oxidized') Crash = File.join Root, 'crash' Log = File.join Root, 'log' InputDir = File.join Directory, %w(lib oxidized input) @@ -27,7 +27,7 @@ module Oxidized asetus.default.timeout = 20 asetus.default.retries = 3 asetus.default.prompt = /^([\w.@-]+[#>]\s?)$/ - asetus.default.rest = '127.0.0.1:8888' # or false to disable + asetus.default.rest = '127.0.0.1:8888' # or false to disable asetus.default.vars = {} # could be 'enable'=>'enablePW' asetus.default.groups = {} # group level configuration diff --git a/lib/oxidized/input/ssh.rb b/lib/oxidized/input/ssh.rb index e7296b5..7ffdd36 100644 --- a/lib/oxidized/input/ssh.rb +++ b/lib/oxidized/input/ssh.rb @@ -26,12 +26,18 @@ module Oxidized if proxy_host = vars(:proxy) proxy = Net::SSH::Proxy::Command.new("ssh #{proxy_host} nc %h %p") end - @ssh = Net::SSH.start(@node.ip, @node.auth[:username], :port => port.to_i, - :password => @node.auth[:password], :timeout => Oxidized.config.timeout, - :paranoid => secure, - :auth_methods => %w(none publickey password keyboard-interactive), - :number_of_password_prompts => 0, - :proxy => proxy) + ssh_opts = { + :port => port.to_i, + :password => @node.auth[:password], :timeout => Oxidized.config.timeout, + :paranoid => secure, + :auth_methods => %w(none publickey password keyboard-interactive), + :number_of_password_prompts => 0, + :proxy => proxy + } + ssh_opts[:kex] = vars(:ssh_kex).split(/,\s*/) if vars(:ssh_kex) + ssh_opts[:encryption] = vars(:ssh_encryption).split(/,\s*/) if vars(:ssh_encryption) + + @ssh = Net::SSH.start(@node.ip, @node.auth[:username], ssh_opts) unless @exec shell_open @ssh begin diff --git a/lib/oxidized/model/airos.rb b/lib/oxidized/model/airos.rb index 316c4f0..775005f 100644 --- a/lib/oxidized/model/airos.rb +++ b/lib/oxidized/model/airos.rb @@ -7,7 +7,7 @@ class Airos < Oxidized::Model cfg.split("\n").map { |line| "# #{line}" }.join("\n") + "\n" end - cmd 'cat /tmp/system.cfg' + cmd 'sort /tmp/system.cfg' cmd :secret do |cfg| cfg.gsub! /^(users\.\d+\.password|snmp\.community)=.+/, "# \\1=<hidden>" diff --git a/lib/oxidized/model/fortios.rb b/lib/oxidized/model/fortios.rb index 3515b46..92add0e 100644 --- a/lib/oxidized/model/fortios.rb +++ b/lib/oxidized/model/fortios.rb @@ -4,6 +4,11 @@ class FortiOS < Oxidized::Model prompt /^([-\w\.]+(\s[\(\w\-\.\)]+)?\~?\s?[#>]\s?)$/ + expect /^--More--\s$/ do |data, re| + send ' ' + data.sub re, '' + end + cmd :all do |cfg, cmdstring| new_cfg = comment "COMMAND: #{cmdstring}\n" new_cfg << cfg.each_line.to_a[1..-2].map { |line| line.gsub(/(conf_file_ver=)(.*)/, '\1<stripped>\3') }.join diff --git a/lib/oxidized/model/ipos.rb b/lib/oxidized/model/ipos.rb new file mode 100644 index 0000000..1a77807 --- /dev/null +++ b/lib/oxidized/model/ipos.rb @@ -0,0 +1,37 @@ +class IPOS < Oxidized::Model + + # Ericsson SSR (IPOS) + # Redback SE (SEOS) + + prompt /^([\[\]\w.@-]+[#>]\s?)$/ + comment '! ' + + cmd 'show chassis' do |cfg| + comment cfg + end + + cmd 'show hardware detail' do |cfg| + comment cfg + end + + cmd 'show release' do |cfg| + comment cfg + end + + cmd 'show config' + + cfg :telnet do + username /^login:/ + password /^\r*password:/ + end + + cfg :telnet, :ssh do + post_login 'terminal length 0' + pre_logout do + send "exit\n" + send "n\n" + end + end + +end + diff --git a/lib/oxidized/model/junos.rb b/lib/oxidized/model/junos.rb index bb56481..bdd9bed 100644 --- a/lib/oxidized/model/junos.rb +++ b/lib/oxidized/model/junos.rb @@ -30,6 +30,8 @@ class JunOS < Oxidized::Model case @model when 'mx960' out << cmd('show chassis fabric reachability') { |cfg| comment cfg } + when /^(ex22|ex33|ex4|ex8|qfx)/ + out << cmd('show virtual-chassis') { |cfg| comment cfg } end out end diff --git a/lib/oxidized/model/mtrlrfs.rb b/lib/oxidized/model/mtrlrfs.rb new file mode 100644 index 0000000..84bcfe1 --- /dev/null +++ b/lib/oxidized/model/mtrlrfs.rb @@ -0,0 +1,37 @@ +class mtrlrfs < Oxidized::Model + + # Motorola RFS/Extreme WM + + comment '# ' + + cmd :all do |cfg| + # xos inserts leading \r characters and other trailing white space. + # this deletes extraneous \r and trailing white space. + cfg.each_line.to_a[1..-2].map{|line|line.delete("\r").rstrip}.join("\n") + "\n" + end + + cmd 'show version' do |cfg| + comment cfg + end + + cmd 'show licenses' do |cfg| + comment cfg + end + + cmd 'show running-config' + + cfg :telnet do + username /^login:/ + password /^\r*password:/ + end + + cfg :telnet, :ssh do + post_login 'terminal length 0' + pre_logout do + send "exit\n" + send "n\n" + end + end + +end + diff --git a/lib/oxidized/model/xos.rb b/lib/oxidized/model/xos.rb index de8ec39..6f1323f 100644 --- a/lib/oxidized/model/xos.rb +++ b/lib/oxidized/model/xos.rb @@ -36,8 +36,10 @@ class XOS < Oxidized::Model cfg :telnet, :ssh do post_login 'disable clipaging' - pre_logout 'exit' - pre_logout 'n' + pre_logout do + send "exit\n" + send "n\n" + end end end diff --git a/spec/cli_spec.rb b/spec/cli_spec.rb new file mode 100644 index 0000000..0a6c91b --- /dev/null +++ b/spec/cli_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' +require 'oxidized/cli' + +describe Oxidized::CLI do + let(:asetus) { mock() } + + after { ARGV.replace @original } + before { @original = ARGV } + + %w[-v --version].each do |option| + describe option do + before { ARGV.replace [option] } + + it 'prints the version and exits' do + Oxidized::Config.expects(:load) + Oxidized.expects(:setup_logger) + Kernel.expects(:exit) + + proc { + Oxidized::CLI.new + }.must_output "#{Oxidized::VERSION}\n" + end + end + end +end |