summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md34
-rwxr-xr-xextra/oxidized.init.d87
-rw-r--r--lib/oxidized/config.rb4
-rw-r--r--lib/oxidized/input/ssh.rb18
-rw-r--r--lib/oxidized/model/edgeswitch.rb6
-rw-r--r--lib/oxidized/model/fortios.rb5
-rw-r--r--lib/oxidized/model/ipos.rb37
-rw-r--r--lib/oxidized/model/mtrlrfs.rb37
-rw-r--r--lib/oxidized/model/nos.rb2
-rw-r--r--lib/oxidized/model/xos.rb6
-rw-r--r--lib/oxidized/output/http.rb58
11 files changed, 280 insertions, 14 deletions
diff --git a/README.md b/README.md
index 1dcc426..5158ed5 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,7 @@ Oxidized is a network device configuration backup tool. It's a RANCID replacemen
* [Source: SQLite](#source-sqlite)
* [Source: HTTP](#source-http)
* [Output: GIT](#output-git)
+ * [Output: HTTP](#output-http)
* [Output: File](#output-file)
* [Output types](#output-types)
* [Advanced Configuration](#advanced-configuration)
@@ -75,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
@@ -94,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
@@ -136,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.
@@ -390,6 +411,19 @@ output:
```
+### Output: Http
+
+POST a config to the specified URL
+
+```
+output:
+ default: http
+ http:
+ user: admin
+ password: changeit
+ url: "http://192.168.162.50:8080/db/coll"
+```
+
### Output types
If you prefer to have different outputs in different files and/or directories, you can easily do this by modifying the corresponding model. To change the behaviour for IOS, you would edit `lib/oxidized/model/ios.rb`.
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/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/edgeswitch.rb b/lib/oxidized/model/edgeswitch.rb
index 89a5690..31014da 100644
--- a/lib/oxidized/model/edgeswitch.rb
+++ b/lib/oxidized/model/edgeswitch.rb
@@ -7,12 +7,12 @@ class EdgeSwitch < Oxidized::Model
prompt /[(]\w*\s\w*[)][\s#>]*[\s#>]/
cmd 'show running-config' do |cfg|
- comment cfg.each_line.reject { |line| line.match /System Up Time.*/ or line.match /Current SNTP Synchronized Time.*/ }.join
+ cfg.each_line.reject { |line| line.match /System Up Time.*/ or line.match /Current SNTP Synchronized Time.*/ }.join
end
cfg :telnet do
username /Username:\s/
- passsword /^Password:\s/
+ password /^Password:\s/
end
cfg :telnet, :ssh do
@@ -22,4 +22,4 @@ class EdgeSwitch < Oxidized::Model
pre_logout 'exit'
end
-end \ No newline at end of file
+end
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/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/nos.rb b/lib/oxidized/model/nos.rb
index 18ca6a2..bd2cb0f 100644
--- a/lib/oxidized/model/nos.rb
+++ b/lib/oxidized/model/nos.rb
@@ -33,7 +33,7 @@ class NOS < Oxidized::Model
cfg :telnet do
username /^.* login: /
- username /^Password:/
+ password /^Password:/
end
cfg :telnet, :ssh do
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/lib/oxidized/output/http.rb b/lib/oxidized/output/http.rb
new file mode 100644
index 0000000..13ba300
--- /dev/null
+++ b/lib/oxidized/output/http.rb
@@ -0,0 +1,58 @@
+module Oxidized
+ class Http < Output
+ attr_reader :commitref
+ def initialize
+ @cfg = Oxidized.config.output.http
+ end
+
+ def setup
+ if @cfg.empty?
+ CFGS.user.output.http.user = 'Oxidized'
+ CFGS.user.output.http.pasword = 'secret'
+ CFGS.user.output.http.url = 'http://localhost/web-api/oxidized'
+ CFGS.save :user
+ raise NoConfig, 'no output http config, edit ~/.config/oxidized/config'
+ end
+ end
+ require "net/http"
+ require "uri"
+ require "json"
+ def store node, outputs, opt={}
+ @commitref = nil
+ json = JSON.pretty_generate(
+ {
+ 'msg' => opt[:msg],
+ 'user' => opt[:user],
+ 'email' => opt[:email],
+ 'group' => opt[:group],
+ 'node' => node,
+ 'config' => outputs.to_cfg,
+ # actually we need to also iterate outputs, for other types like in gitlab. But most people don't use 'type' functionality.
+ }
+ )
+ uri = URI.parse @cfg.url
+ http = Net::HTTP.new uri.host, uri.port
+ #http.use_ssl = true if uri.scheme = 'https'
+ req = Net::HTTP::Post.new(uri.request_uri, initheader = { 'Content-Type' => 'application/json'})
+ req.basic_auth @cfg.user, @cfg.password
+ req.body = json
+ response = http.request req
+
+ case response.code.to_i
+ when 200 || 201
+ Oxidized.logger.info "Configuration http backup complete for #{node}"
+ p [:success]
+ when (400..499)
+ Oxidized.logger.info "Configuration http backup for #{node} failed status: #{response.body}"
+ p [:bad_request]
+ when (500..599)
+ p [:server_problems]
+ Oxidized.logger.info "Configuration http backup for #{node} failed status: #{response.body}"
+ end
+
+ end
+
+ end
+end
+
+