summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md29
-rw-r--r--README.md134
-rwxr-xr-xbin/oxidized3
-rw-r--r--extra/oxidized.service2
-rw-r--r--lib/oxidized.rb5
-rw-r--r--lib/oxidized/config.rb2
-rw-r--r--lib/oxidized/input/cli.rb3
-rw-r--r--lib/oxidized/input/ftp.rb2
-rw-r--r--lib/oxidized/input/ssh.rb35
-rw-r--r--lib/oxidized/input/telnet.rb2
-rw-r--r--lib/oxidized/model/acos.rb16
-rw-r--r--lib/oxidized/model/aosw.rb1
-rw-r--r--lib/oxidized/model/asa.rb5
-rw-r--r--lib/oxidized/model/br6910.rb45
-rw-r--r--lib/oxidized/model/coriant8600.rb30
-rw-r--r--lib/oxidized/model/corianttmos.rb25
-rw-r--r--lib/oxidized/model/cumulus.rb14
-rw-r--r--lib/oxidized/model/datacom.rb7
-rw-r--r--lib/oxidized/model/edgeswitch.rb4
-rw-r--r--lib/oxidized/model/eos.rb1
-rw-r--r--lib/oxidized/model/fortios.rb2
-rw-r--r--lib/oxidized/model/gaiaos.rb46
-rw-r--r--lib/oxidized/model/junos.rb3
-rw-r--r--lib/oxidized/model/model.rb4
-rw-r--r--lib/oxidized/model/pfsense.rb18
-rw-r--r--lib/oxidized/model/procurve.rb2
-rw-r--r--lib/oxidized/model/quantaos.rb35
-rw-r--r--lib/oxidized/model/routeros.rb2
-rw-r--r--lib/oxidized/model/saos.rb6
-rw-r--r--lib/oxidized/model/screenos.rb1
-rw-r--r--lib/oxidized/model/timos.rb71
-rw-r--r--lib/oxidized/node.rb74
-rw-r--r--lib/oxidized/nodes.rb54
-rw-r--r--lib/oxidized/output/file.rb4
-rw-r--r--lib/oxidized/output/git.rb50
-rw-r--r--lib/oxidized/version.rb2
-rw-r--r--oxidized.gemspec5
-rw-r--r--spec/githubrepo_spec.rb15
-rw-r--r--spec/input/ssh_spec.rb1
-rw-r--r--spec/node_spec.rb6
-rw-r--r--spec/nodes_spec.rb1
41 files changed, 600 insertions, 167 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cea6fb4..b85c055 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,32 @@
+# 0.16.3
+- FEATURE: pfsense support (by @stokbaek)
+- BUGFIX: cumulus prompt not working with default switch configs (by @nertwork)
+- BUGFIX: disconnect ssh when prompt wasn't found (by @andir)
+- BUGFIX: saos, asa, acos, timos updates, cumulus
+
+# 0.16.2
+- BUGFIX: when not using git (by @danilopopeye)
+- BUGFIX: screenos update
+
+# 0.16.1
+- BUGFIX: unnecessary puts statement removed from git.rb
+
+# 0.16.0
+- FEATURE: support Gaia OS devices (by @totosh)
+- BUGFIX: #fetch, #version fixes in nodes.rb (by @danilopopeye)
+- BUGFIX: procurve
+
+# 0.15.0
+- FEATURE: disable periodic collection, only on demand (by Adam Winberg)
+- FEATURE: allow disabling ssh exec mode always (mainly for oxidized-script) (by @nickhilliard)
+- FEATURE: support mellanox devices (by @ham5ter)
+- FEATURE: support firewireos devices (by @alexandre-io)
+- FEATURE: support quanta devices (by @f0o)
+- FEATURE: support tellabs coriant8800, coriant8600 (by @udhos)
+- FEATURE: support brocade6910 (by @cardboardpig)
+- BUGFIX: debugging, tests (by @ElvinEfendi)
+- BUGFIX: nos, panos, acos, procurve, eos, edgeswitch, aosw, fortios updates
+
# 0.14.3
- BUGFIX: fix git when using multiple groups without single_repo
diff --git a/README.md b/README.md
index ed66b8a..3c8043f 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,4 @@
-# Oxidized [![Build Status](https://travis-ci.org/Shopify/oxidized.svg)](https://travis-ci.org/Shopify/oxidized)
-
-[![Gem Version](https://badge.fury.io/rb/oxidized.svg)](http://badge.fury.io/rb/oxidized)
+# Oxidized [![Build Status](https://travis-ci.org/Shopify/oxidized.svg)](https://travis-ci.org/Shopify/oxidized) [![Gem Version](https://badge.fury.io/rb/oxidized.svg)](http://badge.fury.io/rb/oxidized) [![Join the chat at https://gitter.im/oxidized/Lobby](https://badges.gitter.im/oxidized/Lobby.svg)](https://gitter.im/oxidized/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Oxidized is a network device configuration backup tool. It's a RANCID replacement!
@@ -20,13 +18,14 @@ Oxidized is a network device configuration backup tool. It's a RANCID replacemen
1. [Supported OS Types](#supported-os-types)
2. [Installation](#installation)
* [Debian](#debian)
- * [CentOS, Oracle Linux, Red Hat Linux version 6](#centos-oracle-linux-red-hat-linux-version 6)
+ * [CentOS, Oracle Linux, Red Hat Linux](#centos-oracle-linux-red-hat-linux)
3. [Initial Configuration](#configuration)
4. [Installing Ruby 2.1.2 using RVM](#installing-ruby-2.1.2-using-rvm)
5. [Running with Docker](#running-with-docker)
6. [Cookbook](#cookbook)
* [Debugging](#debugging)
* [Privileged mode](#privileged-mode)
+ * [Disabling SSH exec channels](#disabling-ssh-exec-channels)
* [Source: CSV](#source-csv)
* [Source: SQLite](#source-sqlite)
* [Source: HTTP](#source-http)
@@ -35,6 +34,7 @@ Oxidized is a network device configuration backup tool. It's a RANCID replacemen
* [Output: File](#output-file)
* [Output types](#output-types)
* [Advanced Configuration](#advanced-configuration)
+ * [Advanced Group Configuration](#advanced-group-configuration)
7. [Ruby API](#ruby-api)
* [Input](#input)
* [Output](#output)
@@ -49,7 +49,6 @@ Oxidized is a network device configuration backup tool. It's a RANCID replacemen
* AOS
* AOS7
* ISAM
- * TiMOS
* Wireless
* Arista
* EOS
@@ -62,6 +61,9 @@ Oxidized is a network device configuration backup tool. It's a RANCID replacemen
* Ironware
* NOS (Network Operating System)
* Vyatta
+ * 6910
+ * Check Point
+ * GaiaOS
* Ciena
* SOAS
* Cisco
@@ -74,6 +76,9 @@ Oxidized is a network device configuration backup tool. It's a RANCID replacemen
* SMB (Nikola series)
* Citrix
* NetScaler (Virtual Applicance)
+ * Coriant (former Tellabs)
+ * TMOS (8800)
+ * 8600
* Cumulus
* Linux
* DataCom
@@ -111,10 +116,15 @@ Oxidized is a network device configuration backup tool. It's a RANCID replacemen
* MasterOS
* Netonix
* WISP Switch (As Netonix)
+ * Nokia (formerly TiMetra, Alcatel, Alcatel-Lucent)
+ * SR OS (TiMOS)
* Opengear
* Opengear
* Palo Alto
* PANOS
+ * pfSense
+ * Quanta
+ * Quanta / VxWorks 6.6 (1.1.0.8)
* Supermicro
* Supermicro
* Ubiquiti
@@ -137,13 +147,19 @@ gem install oxidized
gem install oxidized-script oxidized-web # if you don't install oxidized-web, make sure you remove "rest" from your config
```
-## CentOS, Oracle Linux, Red Hat Linux version 6
-Install Ruby 1.9.3 or greater (for Ruby 2.1.2 installation instructions see "Installing Ruby 2.1.2 using RVM"), then install Oxidized dependencies
+## CentOS, Oracle Linux, Red Hat Linux
+On CentOS 6 / RHEL 6, install Ruby 1.9.3 or greater (for Ruby 2.1.2 installation instructions see "Installing Ruby 2.1.2 using RVM"), then install Oxidized dependencies
```shell
yum install cmake sqlite-devel openssl-devel libssh2-devel
```
-Now lets install oxidized via Rubygems:
+RHEL 7 / CentOS 7 will work out of the box with the following package list:
+
+```shell
+yum install cmake sqlite-devel openssl-devel libssh2-devel ruby gcc ruby-devel
+```
+
+Now let's install oxidized via Rubygems:
```shell
gem install oxidized
gem install oxidized-script oxidized-web
@@ -153,6 +169,14 @@ gem install oxidized-script oxidized-web
Oxidized configuration is in YAML format. Configuration files are subsequently sourced from ```/etc/oxidized/config``` then ```~/.config/oxidized/config```. The hashes will be merged, this might be useful for storing source information in a system wide file and user specific configuration in the home directory (to only include a staff specific username and password). Eg. if many users are using ```oxs```, see [Oxidized::Script](https://github.com/ytti/oxidized-script).
+It is recommended practice to run Oxidized using its own username. This username can be added using standard command-line tools:
+
+```
+useradd oxidized
+```
+
+It is recommended not to run Oxidized as root.
+
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.
@@ -231,46 +255,54 @@ rvm use --default 2.1.2
```
# Running with Docker
-1. clone git repo:
+
+clone git repo:
```
- root@bla:~# git clone https://github.com/ytti/oxidized
-```
-2. build container locally:
+git clone https://github.com/ytti/oxidized
```
- root@bla:~# docker build -q -t oxidized/oxidized:latest oxidized/
+
+build container locally:
+
```
-3. create config directory in main system:
+docker build -q -t oxidized/oxidized:latest oxidized/
```
- root@bla~:# mkdir /etc/oxidized
+
+create config directory in main system:
+
```
-4. run container the first time:
+mkdir /etc/oxidized
```
- root@bla:~# docker run -v /etc/oxidized:/root/.config/oxidized -p 8888:8888/tcp -t oxidized/oxidized:latest oxidized
+
+run container the first time:
+_Note: this step in only needed for creating Oxidized's configuration file and can be skipped if you already have it
+
```
-5. add 'router.db' to /etc/oxidized:
+docker run --rm -v /etc/oxidized:/root/.config/oxidized -p 8888:8888/tcp -t oxidized/oxidized:latest oxidized
```
- root@bla:~# vim /etc/oxidized/router.db
- [ ... ]
- root@bla:~#
+
+create the `/etc/oxidized/router.db`
+
```
-6. run container again:
+vim /etc/oxidized/router.db
```
- root@bla:~# docker run -v /etc/oxidized:/root/.config/oxidized -p 8888:8888/tcp -t oxidized/oxidized:latest
- oxidized[1]: Oxidized starting, running as pid 1
- oxidized[1]: Loaded 1 nodes
- Puma 2.13.4 starting...
- * Min threads: 0, max threads: 16
- * Environment: development
- * Listening on tcp://0.0.0.0:8888
- ^C
- root@bla:~#
+run container again:
+
+```
+docker run -v /etc/oxidized:/root/.config/oxidized -p 8888:8888/tcp -t oxidized/oxidized:latest
+oxidized[1]: Oxidized starting, running as pid 1
+oxidized[1]: Loaded 1 nodes
+Puma 2.13.4 starting...
+* Min threads: 0, max threads: 16
+* Environment: development
+* Listening on tcp://0.0.0.0:8888
```
If you want to have the config automatically reloaded (e.g. when using a http source that changes)
+
```
- root@bla:~# docker run -v /etc/oxidized:/root/.config/oxidized -p 8888:8888/tcp -e CONFIG_RELOAD_INTERVAL=3600 -t oxidized/oxidized:latest
+docker run -v /etc/oxidized:/root/.config/oxidized -p 8888:8888/tcp -e CONFIG_RELOAD_INTERVAL=3600 -t oxidized/oxidized:latest
```
## Cookbook
@@ -320,6 +352,16 @@ The above strips out snmp community strings from your saved configs.
**NOTE:** Removing secrets reduces the usefulness as a full configuration backup, but it may make sharing configs easier.
+### Disabling SSH exec channels
+
+Oxidized uses exec channels to make information extraction simpler, but there are some situations where this doesn't work well, e.g. configuring devices. This feature can be turned off by setting the ```ssh_no_exec```
+variable.
+
+```
+vars:
+ ssh_no_exec: true
+```
+
### Source: CSV
One line per device, colon seperated.
@@ -387,6 +429,8 @@ source:
url: https://url/api
scheme: https
delimiter: !ruby/regexp /:/
+ user: username
+ pass: password
map:
name: hostname
model: os
@@ -477,7 +521,7 @@ output:
### 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`.
+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` (run `gem contents oxidized` to find out the full file path).
For example, let's say you want to split out `show version` and `show inventory` into separate files in a directory called `nodiff` which your tools will not send automated diffstats for. You can apply a patch along the lines of
@@ -537,7 +581,7 @@ rest: 10.0.0.1:8000/oxidized
### Advanced Configuration
-Below is an advanced example configuration. You will be able to (optinally) override options per device. The router.db format used is ```hostname:model:username:password:enable_password```. Hostname and model will be the only required options, all others override the global configuration sections.
+Below is an advanced example configuration. You will be able to (optionally) override options per device. The router.db format used is ```hostname:model:username:password:enable_password```. Hostname and model will be the only required options, all others override the global configuration sections.
```
---
@@ -582,6 +626,28 @@ source:
model_map:
cisco: ios
juniper: junos
+
+```
+
+### Advanced Group Configuration
+
+For group specific credentials
+
+```
+groups:
+ mikrotik:
+ username: admin
+ password: blank
+ ubiquiti:
+ username: ubnt
+ password: ubnt
+```
+and add group mapping
+```
+map:
+ model: 0
+ name: 1
+ group: 2
```
# Hooks
diff --git a/bin/oxidized b/bin/oxidized
index 2695a52..7a0b03d 100755
--- a/bin/oxidized
+++ b/bin/oxidized
@@ -9,5 +9,6 @@ begin
Oxidized::CLI.new.run
rescue => error
warn "#{error}"
- raise if Oxidized.config.debug
+ debug = Oxidied.config.debug rescue true
+ raise if debug
end
diff --git a/extra/oxidized.service b/extra/oxidized.service
index 65063b7..ba60bd5 100644
--- a/extra/oxidized.service
+++ b/extra/oxidized.service
@@ -6,7 +6,7 @@ Description=Oxidized - Network Device Configuration Backup Tool
[Service]
ExecStart=/usr/local/bin/oxidized
-User=root
+User=oxidized
[Install]
WantedBy=multi-user.target
diff --git a/lib/oxidized.rb b/lib/oxidized.rb
index dfd9679..ce48f10 100644
--- a/lib/oxidized.rb
+++ b/lib/oxidized.rb
@@ -1,3 +1,5 @@
+require 'fileutils'
+
module Oxidized
class OxidizedError < StandardError; end
@@ -34,13 +36,14 @@ module Oxidized
end
def self.setup_logger
+ FileUtils.mkdir_p(Config::Log) unless File.directory?(Config::Log)
self.logger = if config.has_key?('use_syslog') && config.use_syslog
require 'syslog/logger'
Syslog::Logger.new('oxidized')
else
require 'logger'
if config.has_key?('log')
- Logger.new(config.log)
+ Logger.new(File.expand_path(config.log))
else
Logger.new(STDERR)
end
diff --git a/lib/oxidized/config.rb b/lib/oxidized/config.rb
index 1797be6..b6b5c40 100644
--- a/lib/oxidized/config.rb
+++ b/lib/oxidized/config.rb
@@ -5,7 +5,7 @@ module Oxidized
class Config
Root = ENV['OXIDIZED_HOME'] || File.join(ENV['HOME'], '.config', 'oxidized')
Crash = File.join Root, 'crash'
- Log = File.join Root, 'log'
+ Log = File.join Root, 'logs'
InputDir = File.join Directory, %w(lib oxidized input)
OutputDir = File.join Directory, %w(lib oxidized output)
ModelDir = File.join Directory, %w(lib oxidized model)
diff --git a/lib/oxidized/input/cli.rb b/lib/oxidized/input/cli.rb
index fc7f426..660e173 100644
--- a/lib/oxidized/input/cli.rb
+++ b/lib/oxidized/input/cli.rb
@@ -14,6 +14,9 @@ module Oxidized
d = node.model.get
disconnect
d
+ rescue PromptUndetect
+ disconnect
+ raise
end
def connect_cli
diff --git a/lib/oxidized/input/ftp.rb b/lib/oxidized/input/ftp.rb
index c6d644c..80de257 100644
--- a/lib/oxidized/input/ftp.rb
+++ b/lib/oxidized/input/ftp.rb
@@ -18,7 +18,7 @@ module Oxidized
def connect node
@node = node
@node.model.cfg['ftp'].each { |cb| instance_exec(&cb) }
- @log = File.open(Oxidized::Config::Log + "-#{@node.ip}-ftp", 'w') if Oxidized.config.input.debug?
+ @log = File.open(Oxidized::Config::Log + "/#{@node.ip}-ftp", 'w') if Oxidized.config.input.debug?
@ftp = Net::FTP.new @node.ip, @node.auth[:username], @node.auth[:password]
connected?
end
diff --git a/lib/oxidized/input/ssh.rb b/lib/oxidized/input/ssh.rb
index db39a7e..c0b7cf9 100644
--- a/lib/oxidized/input/ssh.rb
+++ b/lib/oxidized/input/ssh.rb
@@ -21,7 +21,7 @@ module Oxidized
@output = ''
@node.model.cfg['ssh'].each { |cb| instance_exec(&cb) }
secure = Oxidized.config.input.ssh.secure
- @log = File.open(Oxidized::Config::Log + "-#{@node.ip}-ssh", 'w') if Oxidized.config.input.debug?
+ @log = File.open(Oxidized::Config::Log + "/#{@node.ip}-ssh", 'w') if Oxidized.config.input.debug?
port = vars(:ssh_port) || 22
if proxy_host = vars(:ssh_proxy)
proxy = Net::SSH::Proxy::Command.new("ssh #{proxy_host} -W %h:%p")
@@ -42,7 +42,7 @@ module Oxidized
unless @exec
shell_open @ssh
begin
- @username ? shell_login : expect(@node.prompt)
+ login
rescue Timeout::Error
raise PromptUndetect, [ @output, 'not matching configured prompt', @node.prompt ].join(' ')
end
@@ -102,17 +102,22 @@ module Oxidized
end
end
- # Cisco WCS has extremely dubious SSH implementation, SSH auth is always
- # success, it always opens shell and then run auth in shell. I guess
- # they'll never support exec() :)
- def shell_login
- expect username
- cmd @node.auth[:username], password
- cmd @node.auth[:password]
+ # some models have SSH auth or terminal auth based on version of code
+ # if SSH is configured for terminal auth, we'll still try to detect prompt
+ def login
+ if @username
+ match = expect username, @node.prompt
+ if match == username
+ cmd @node.auth[:username], password
+ cmd @node.auth[:password]
+ end
+ else
+ expect @node.prompt
+ end
end
def exec state=nil
- state == nil ? @exec : (@exec=state)
+ state == nil ? @exec : (@exec=state) unless vars :ssh_no_exec
end
def cmd_shell(cmd, expect_re)
@@ -123,14 +128,18 @@ module Oxidized
@output
end
- def expect regexp
- Oxidized.logger.debug "lib/oxidized/input/ssh.rb: expecting #{regexp.inspect} at #{node.name}"
+ def expect *regexps
+ regexps = [regexps].flatten
+ Oxidized.logger.debug "lib/oxidized/input/ssh.rb: expecting #{regexps.inspect} at #{node.name}"
Timeout::timeout(Oxidized.config.timeout) do
@ssh.loop(0.1) do
sleep 0.1
- not @output.match regexp
+ match = regexps.find { |regexp| @output.match regexp }
+ return match if match
+ true
end
end
end
+
end
end
diff --git a/lib/oxidized/input/telnet.rb b/lib/oxidized/input/telnet.rb
index 3446ca2..a5561b9 100644
--- a/lib/oxidized/input/telnet.rb
+++ b/lib/oxidized/input/telnet.rb
@@ -16,7 +16,7 @@ module Oxidized
'Port' => port.to_i,
'Timeout' => @timeout,
'Model' => @node.model }
- opt['Output_log'] = Oxidized::Config::Log + "-#{@node.ip}-telnet" if Oxidized.config.input.debug?
+ opt['Output_log'] = Oxidized::Config::Log + "/#{@node.ip}-telnet" if Oxidized.config.input.debug?
@telnet = Net::Telnet.new opt
if @node.auth[:username] and @node.auth[:username].length > 0
diff --git a/lib/oxidized/model/acos.rb b/lib/oxidized/model/acos.rb
index bb9846e..47649a2 100644
--- a/lib/oxidized/model/acos.rb
+++ b/lib/oxidized/model/acos.rb
@@ -6,6 +6,13 @@ class ACOS < Oxidized::Model
##ACOS prompt changes depending on the state of the device
prompt /^([-\w.\/:?\[\]\(\)]+[#>]\s?)$/
+ cmd :secret do |cfg|
+ cfg.gsub!(/community read encrypted (\S+)/, 'community read encrypted <hidden>') # snmp
+ cfg.gsub!(/secret encrypted (\S+)/, 'secret encrypted <hidden>') # tacacs-server
+ cfg.gsub!(/password encrypted (\S+)/, 'password encrypted <hidden>') # user
+ cfg
+ end
+
cmd 'show version' do |cfg|
cfg.gsub! /\s(Last configuration saved at).*/, ' \\1 <removed>'
cfg.gsub! /\s(Memory).*/, ' \\1 <removed>'
@@ -22,11 +29,20 @@ class ACOS < Oxidized::Model
comment cfg
end
+ cmd 'show partition-config all' do |cfg|
+ cfg.gsub! /(Current configuration).*/, '\\1 <removed>'
+ cfg.gsub! /(Configuration last updated at).*/, '\\1 <removed>'
+ cfg.gsub! /(Configuration last saved at).*/, '\\1 <removed>'
+ cfg.gsub! /(Configuration last synchronized at).*/, '\\1 <removed>'
+ cfg
+ end
+
cmd 'show running-config all-partitions' do |cfg|
cfg.gsub! /(Current configuration).*/, '\\1 <removed>'
cfg.gsub! /(Configuration last updated at).*/, '\\1 <removed>'
cfg.gsub! /(Configuration last saved at).*/, '\\1 <removed>'
cfg.gsub! /(Configuration last synchronized at).*/, '\\1 <removed>'
+ cfg
end
cmd 'show aflex all-partitions' do |cfg|
diff --git a/lib/oxidized/model/aosw.rb b/lib/oxidized/model/aosw.rb
index 4f09e51..394561f 100644
--- a/lib/oxidized/model/aosw.rb
+++ b/lib/oxidized/model/aosw.rb
@@ -22,6 +22,7 @@ class AOSW < Oxidized::Model
cfg.gsub!(/key (\S+)$/, 'key <secret removed>')
cfg.gsub!(/secret (\S+)$/, 'secret <secret removed>')
cfg.gsub!(/wpa-passphrase (\S+)$/, 'wpa-passphrase <secret removed>')
+ cfg.gsub!(/bkup-passwords (\S+)$/, 'bkup-passwords <secret removed>')
cfg
end
diff --git a/lib/oxidized/model/asa.rb b/lib/oxidized/model/asa.rb
index 317463d..df30059 100644
--- a/lib/oxidized/model/asa.rb
+++ b/lib/oxidized/model/asa.rb
@@ -13,6 +13,9 @@ class ASA < Oxidized::Model
cmd :secret do |cfg|
cfg.gsub! /enable password (\S+) (.*)/, 'enable password <secret hidden> \2'
cfg.gsub! /username (\S+) password (\S+) (.*)/, 'username \1 password <secret hidden> \3'
+ cfg.gsub! /ikev2 pre-shared-key (\S+)/, 'ikev2 pre-shared-key <secret hidden>'
+ cfg.gsub! /ikev2 (remote|local)-authentication pre-shared-key (\S+)/, 'ikev2 \1-authentication pre-shared-key <secret hidden>'
+ cfg.gsub! /^(aaa-server TACACS\+? \(\S+\) host.*\n\skey) \S+$/mi, '\1 <secret hidden>'
cfg
end
@@ -52,7 +55,7 @@ class ASA < Oxidized::Model
if vars :enable
post_login do
send "enable\n"
- send vars(:enable) + "\n"
+ cmd vars(:enable)
end
end
post_login 'terminal pager 0'
diff --git a/lib/oxidized/model/br6910.rb b/lib/oxidized/model/br6910.rb
new file mode 100644
index 0000000..b5c9bcf
--- /dev/null
+++ b/lib/oxidized/model/br6910.rb
@@ -0,0 +1,45 @@
+
+class BR6910 < Oxidized::Model
+
+ prompt /^Vty-[0-9]\#$/
+ comment '! '
+
+ # not possible to disable paging prior to show running-config
+ expect /^((.*)Others to exit ---(.*))$/ do |data, re|
+ send 'a'
+ data.sub re, ''
+ end
+
+ cmd :all do |cfg|
+ # sometimes br6910s inserts arbitrary whitespace after commands are
+ # issued on the CLI, from run to run. this normalises the output.
+ cfg.each_line.to_a[1..-2].drop_while { |e| e.match /^\s+$/ }.join
+ end
+
+ cmd 'show version' do |cfg|
+ comment cfg
+ end
+
+ # show flash is not possible on a brocade 6910, do dir instead
+ # to see flash contents (includes config file names)
+ cmd 'dir' do |cfg|
+ comment cfg
+ end
+
+ cmd 'show running-config' do |cfg|
+ arr = cfg.each_line.to_a
+ arr[2..-1].join unless arr.length < 2
+ end
+
+ cfg :telnet do
+ username /^Username:/
+ password /^Password:/
+ end
+
+ # post login and post logout
+ cfg :telnet, :ssh do
+ post_login ''
+ pre_logout 'exit'
+ end
+
+end
diff --git a/lib/oxidized/model/coriant8600.rb b/lib/oxidized/model/coriant8600.rb
new file mode 100644
index 0000000..a48ffa5
--- /dev/null
+++ b/lib/oxidized/model/coriant8600.rb
@@ -0,0 +1,30 @@
+class Coriant8600 < Oxidized::Model
+
+ comment '# '
+
+ prompt /^[^\s#>]+[#>]$/
+
+ cmd 'show hw-inventory' do |cfg|
+ comment cfg
+ end
+
+ cmd 'show flash' do |cfg|
+ comment cfg
+ end
+
+ cmd 'show run' do |cfg|
+ cfg
+ end
+
+ cfg :telnet do
+ username /^user name:$/
+ password /^password:$/
+ end
+
+ cfg :telnet, :ssh do
+ pre_logout 'exit'
+ post_login 'enable'
+ post_login 'terminal more off'
+ end
+
+end
diff --git a/lib/oxidized/model/corianttmos.rb b/lib/oxidized/model/corianttmos.rb
new file mode 100644
index 0000000..76603f6
--- /dev/null
+++ b/lib/oxidized/model/corianttmos.rb
@@ -0,0 +1,25 @@
+class CoriantTmos < Oxidized::Model
+
+ comment '# '
+
+ prompt /^[^\s#]+#\s$/
+
+ cmd 'show node extensive' do |cfg|
+ comment cfg
+ end
+
+ cmd 'show run' do |cfg|
+ cfg
+ end
+
+ cfg :telnet do
+ username /^Login:\s$/
+ password /^Password:\s$/
+ end
+
+ cfg :telnet, :ssh do
+ pre_logout 'exit'
+ post_login 'enable config terminal length 0'
+ end
+
+end
diff --git a/lib/oxidized/model/cumulus.rb b/lib/oxidized/model/cumulus.rb
index 68d856e..dc6792a 100644
--- a/lib/oxidized/model/cumulus.rb
+++ b/lib/oxidized/model/cumulus.rb
@@ -1,6 +1,6 @@
class Cumulus < Oxidized::Model
- prompt /^((\w*)@(.*)([>#]\s)+)$/
+ prompt /^((\w*)@(.*)):/
comment '# '
@@ -22,7 +22,7 @@ class Cumulus < Oxidized::Model
cfg += cmd 'cat /etc/hosts'
cfg += add_comment 'THE INTERFACES'
- cfg += cmd 'cat /etc/network/interfaces'
+ cfg += cmd 'grep -r "" /etc/network/interface* | cut -d "/" -f 4-'
cfg += add_comment 'RESOLV.CONF'
cfg += cmd 'cat /etc/resolv.conf'
@@ -30,6 +30,9 @@ class Cumulus < Oxidized::Model
cfg += add_comment 'NTP.CONF'
cfg += cmd 'cat /etc/ntp.conf'
+ cfg += add_comment 'IP Routes'
+ cfg += cmd 'netstat -rn'
+
cfg += add_comment 'QUAGGA DAEMONS'
cfg += cmd 'cat /etc/quagga/daemons'
@@ -55,10 +58,13 @@ class Cumulus < Oxidized::Model
cfg += cmd 'cat /etc/cumulus/switchd.conf'
cfg += add_comment 'ACL'
- cfg += cmd 'iptables -L'
+ cfg += cmd 'iptables -L -n'
cfg += add_comment 'VERSION'
cfg += cmd 'cat /etc/cumulus/etc.replace/os-release'
+
+ cfg += add_comment 'License'
+ cfg += cmd 'cl-license'
end
@@ -73,4 +79,4 @@ class Cumulus < Oxidized::Model
end
-end \ No newline at end of file
+end
diff --git a/lib/oxidized/model/datacom.rb b/lib/oxidized/model/datacom.rb
index 54091ed..5dbc080 100644
--- a/lib/oxidized/model/datacom.rb
+++ b/lib/oxidized/model/datacom.rb
@@ -24,7 +24,12 @@ class DataCom < Oxidized::Model
cfg.cut_head
end
- cfg :telnet, :ssh do
+ cfg :ssh do
+ password /^Password:\s$/
+ pre_logout 'exit'
+ end
+
+ cfg :telnet do
username /login:\s$/
password /^Password:\s$/
pre_logout 'exit'
diff --git a/lib/oxidized/model/edgeswitch.rb b/lib/oxidized/model/edgeswitch.rb
index 7c82639..7f5b1ea 100644
--- a/lib/oxidized/model/edgeswitch.rb
+++ b/lib/oxidized/model/edgeswitch.rb
@@ -11,8 +11,8 @@ class EdgeSwitch < Oxidized::Model
end
cfg :telnet do
- username /Username:\s/
- password /^Password:\s/
+ username /User(name)?:\s?/
+ password /^Password:\s?/
end
cfg :telnet, :ssh do
diff --git a/lib/oxidized/model/eos.rb b/lib/oxidized/model/eos.rb
index 84ef8cb..75da0fa 100644
--- a/lib/oxidized/model/eos.rb
+++ b/lib/oxidized/model/eos.rb
@@ -14,6 +14,7 @@ class EOS < Oxidized::Model
cfg.gsub! /^(snmp-server community).*/, '\\1 <configuration removed>'
cfg.gsub! /username (\S+) privilege (\d+) (\S+).*/, '<secret hidden>'
cfg.gsub! /^(enable secret).*/, '\\1 <configuration removed>'
+ cfg.gsub! /^(tacacs-server key \d+).*/, '\\1 <configuration removed>'
cfg
end
diff --git a/lib/oxidized/model/fortios.rb b/lib/oxidized/model/fortios.rb
index aad3a6e..cd379b7 100644
--- a/lib/oxidized/model/fortios.rb
+++ b/lib/oxidized/model/fortios.rb
@@ -2,7 +2,7 @@ class FortiOS < Oxidized::Model
comment '# '
- prompt /^([-\w\.]+(\s[\(\w\-\.\)]+)?\~?\s?[#>$]\s?)$/
+ prompt /^([-\w\.\~]+(\s[\(\w\-\.\)]+)?\~?\s?[#>$]\s?)$/
expect /^--More--\s$/ do |data, re|
send ' '
diff --git a/lib/oxidized/model/gaiaos.rb b/lib/oxidized/model/gaiaos.rb
new file mode 100644
index 0000000..434e774
--- /dev/null
+++ b/lib/oxidized/model/gaiaos.rb
@@ -0,0 +1,46 @@
+class GaiaOS < Oxidized::Model
+
+ # CheckPoint - Gaia OS Model
+
+ # Gaia Prompt
+ prompt /^([\[\]\w.@:-]+[#>]\s?)$/
+
+ # Comment tag
+ comment '# '
+
+
+ cmd :all do |cfg|
+ cfg = cfg.each_line.to_a[1..-2].join
+ end
+
+ cmd :secret do |cfg|
+ cfg.gsub! /^(set expert-password-hash ).*/, '\1<EXPERT PASSWORD REMOVED>'
+ cfg.gsub! /^(set user \S+ password-hash ).*/,'\1<USER PASSWORD REMOVED>'
+ cfg.gsub! /^(set ospf .* secret ).*/,'\1<OSPF KEY REMOVED>'
+ cfg.gsub! /^(set snmp community )(.*)( read-only.*)/,'\1<SNMP COMMUNITY REMOVED>\3'
+ cfg.gsub! /^(add snmp .* community )(.*)(\S?.*)/,'\1<SNMP COMMUNITY REMOVED>\3'
+ cfg.gsub! /(auth|privacy)(-pass-phrase-hashed )(\S*)/,'\1-pass-phrase-hashed <SNMP PASS-PHRASE REMOVED>'
+ cfg
+ end
+
+ cmd 'show asset all' do |cfg|
+ comment cfg
+ end
+
+ cmd 'show version all' do |cfg|
+ comment cfg
+ end
+
+ cmd 'show configuration' do |cfg|
+ cfg.gsub! /^# Exported by \S+ on .*/, '# '
+ cfg
+ end
+
+
+ cfg :ssh do
+ # User shell must be /etc/cli.sh
+ post_login 'set clienv rows 0'
+ pre_logout 'exit'
+ end
+
+end
diff --git a/lib/oxidized/model/junos.rb b/lib/oxidized/model/junos.rb
index bdd9bed..058e3cf 100644
--- a/lib/oxidized/model/junos.rb
+++ b/lib/oxidized/model/junos.rb
@@ -7,8 +7,7 @@ class JunOS < Oxidized::Model
end
cmd :all do |cfg|
- # we don't need screen-scraping in ssh due to exec
- cfg = cfg.lines.to_a[1..-2].join if telnet
+ cfg = cfg.lines.to_a[1..-2].join if screenscrape
cfg.lines.map { |line| line.rstrip }.join("\n") + "\n"
end
diff --git a/lib/oxidized/model/model.rb b/lib/oxidized/model/model.rb
index 4a15a45..a2a71cb 100644
--- a/lib/oxidized/model/model.rb
+++ b/lib/oxidized/model/model.rb
@@ -154,6 +154,10 @@ module Oxidized
data
end
+ def screenscrape
+ @input.class.to_s.match(/Telnet/) || vars(:ssh_no_exec)
+ end
+
private
def process_cmd_output output, name
diff --git a/lib/oxidized/model/pfsense.rb b/lib/oxidized/model/pfsense.rb
new file mode 100644
index 0000000..9982d72
--- /dev/null
+++ b/lib/oxidized/model/pfsense.rb
@@ -0,0 +1,18 @@
+class PfSense < Oxidized::Model
+
+ # use other use than 'admin' user, 'admin' user cannot get ssh/exec. See issue #535
+
+ cmd :all do |cfg|
+ cfg.each_line.to_a[1..-2].join
+ end
+
+ cmd 'cat /cf/conf/config.xml' do |cfg|
+ cfg.gsub! /\s<revision>\s*<time>\d*<\/time>\s*.*\s*.*\s*<\/revision>/, ''
+ end
+
+ cfg :ssh do
+ exec true
+ pre_logout 'exit'
+ end
+
+end
diff --git a/lib/oxidized/model/procurve.rb b/lib/oxidized/model/procurve.rb
index 0dc6f8f..da792e6 100644
--- a/lib/oxidized/model/procurve.rb
+++ b/lib/oxidized/model/procurve.rb
@@ -11,7 +11,7 @@ class Procurve < Oxidized::Model
data.gsub re, ''
end
- expect /Press any key to continue/ do
+ expect /Press any key to continue(\e\[\??\d+(;\d+)*[A-Za-z])*$/ do
send ' '
""
end
diff --git a/lib/oxidized/model/quantaos.rb b/lib/oxidized/model/quantaos.rb
new file mode 100644
index 0000000..274440d
--- /dev/null
+++ b/lib/oxidized/model/quantaos.rb
@@ -0,0 +1,35 @@
+class QuantaOS < Oxidized::Model
+
+ prompt /^\((\w|\S)+\) (>|#)$/
+ comment '! '
+
+ cmd 'show run' do |cfg|
+ cfg.each_line.select do |line|
+ not line.match /^!.*$/ and
+ not line.match /^\((\w|\S)+\) (>|#)$/ and
+ not line.match /^show run$/
+ end.join
+ end
+
+ cfg :telnet do
+ username /^Username:/
+ password /^Password:/
+ end
+
+ cfg :telnet, :ssh do
+ post_login do
+ send "enable\n"
+ if vars :enable
+ cmd vars(:enable)
+ else
+ cmd ""
+ end
+ end
+ post_login 'terminal length 0'
+ pre_logout do
+ send "quit\n"
+ send "n\n"
+ end
+ end
+
+end
diff --git a/lib/oxidized/model/routeros.rb b/lib/oxidized/model/routeros.rb
index 4822500..fc96512 100644
--- a/lib/oxidized/model/routeros.rb
+++ b/lib/oxidized/model/routeros.rb
@@ -1,5 +1,5 @@
class RouterOS < Oxidized::Model
- prompt /\[\w+@\S+\]\s?>\s?$/
+ prompt /\[\w+@\S+(\s?\S+)*\]\s?>\s?$/
comment "# "
cmd '/system routerboard print' do |cfg|
diff --git a/lib/oxidized/model/saos.rb b/lib/oxidized/model/saos.rb
index cada35b..5d460cf 100644
--- a/lib/oxidized/model/saos.rb
+++ b/lib/oxidized/model/saos.rb
@@ -17,8 +17,10 @@ class SAOS < Oxidized::Model
username /login:/
password /assword:/
end
- cfg :telnet do
+
+ cfg :telnet, :ssh do
+ post_login 'system shell set more off'
post_login 'system shell session set more off'
pre_logout 'exit'
end
-end \ No newline at end of file
+end
diff --git a/lib/oxidized/model/screenos.rb b/lib/oxidized/model/screenos.rb
index 7ee9d9f..0258898 100644
--- a/lib/oxidized/model/screenos.rb
+++ b/lib/oxidized/model/screenos.rb
@@ -20,6 +20,7 @@ class ScreenOS < Oxidized::Model
cmd 'get system' do |cfg|
cfg.gsub! /^Date\ .*\n/, ''
cfg.gsub! /^Up\ .*\n/, ''
+ cfg.gsub! /(current bw ).*/, '\\1 <removed>'
comment cfg
end
diff --git a/lib/oxidized/model/timos.rb b/lib/oxidized/model/timos.rb
index dc28580..d40e845 100644
--- a/lib/oxidized/model/timos.rb
+++ b/lib/oxidized/model/timos.rb
@@ -1,8 +1,10 @@
class TiMOS < Oxidized::Model
- # Alcatel-Lucent TiMOS (Timetra)
- # used in SR/ESS/SAS routers
-
+ #
+ # Nokia SR OS (TiMOS) (formerly TiMetra, Alcatel, Alcatel-Lucent).
+ # Used in 7705 SAR, 7210 SAS, 7450 ESS, 7750 SR, 7950 XRS, and NSP.
+ #
+
comment '# '
prompt /^([-\w\.:>\*]+\s?[#>]\s?)$/
@@ -12,26 +14,81 @@ class TiMOS < Oxidized::Model
new_cfg << cfg.each_line.to_a[1..-2].join
end
+ #
+ # Show the boot options file.
+ #
cmd 'show bof' do |cfg|
comment cfg
end
+ #
+ # Show the system information.
+ #
cmd 'show system information' do |cfg|
- # strip uptime
+ #
+ # Strip uptime.
+ #
cfg.sub! /^System Up Time.*\n/, ''
comment cfg
end
+ #
+ # Show the card state.
+ #
cmd 'show card state' do |cfg|
comment cfg
end
- cmd 'show boot-messages' do |cfg|
- cfg.gsub! /\r/, ""
+ #
+ # Show the boot log.
+ #
+ cmd 'file type bootlog.txt' do |cfg|
+ #
+ # Strip carriage returns and backspaces.
+ #
+ cfg.gsub! /\r/, ''
+ cfg.gsub! /[\b][\b][\b]/, "\n"
+ comment cfg
+ end
+
+ #
+ # Show the running debug configuration.
+ #
+ cmd 'show debug' do |cfg|
comment cfg
end
- cmd 'admin display-config'
+ #
+ # Show the saved debug configuration (admin debug-save).
+ #
+ cmd 'file type config.dbg' do |cfg|
+ #
+ # Strip carriage returns.
+ #
+ cfg.gsub! /\r/, ''
+ comment cfg
+ end
+
+ #
+ # Show the running persistent indices.
+ #
+ cmd 'admin display-config index' do |cfg|
+ #
+ # Strip carriage returns.
+ #
+ cfg.gsub! /\r/, ''
+ comment cfg
+ end
+
+ #
+ # Show the running configuration.
+ #
+ cmd 'admin display-config' do |cfg|
+ #
+ # Strip carriage returns.
+ #
+ cfg.gsub! /\r/, ''
+ end
cfg :telnet do
username /^Login: /
diff --git a/lib/oxidized/node.rb b/lib/oxidized/node.rb
index cc1e406..c93a16a 100644
--- a/lib/oxidized/node.rb
+++ b/lib/oxidized/node.rb
@@ -9,9 +9,7 @@ module Oxidized
attr_accessor :running, :user, :msg, :from, :stats, :retry
alias :running? :running
def initialize opt
- if Oxidized.config.debug == true or opt[:debug] == true
- puts 'resolving DNS for %s...' % opt[:name]
- end
+ Oxidized.logger.debug 'resolving DNS for %s...' % opt[:name]
@name = opt[:name]
@ip = IPAddr.new(opt[:ip]).to_s rescue nil
@ip ||= Resolv.new.getaddress @name
@@ -24,7 +22,7 @@ module Oxidized
@vars = opt[:vars]
@stats = Stats.new
@retry = 0
- @repo = resolve_repo
+ @repo = resolve_repo opt
# model instance needs to access node instance
@model.node = self
@@ -130,24 +128,15 @@ module Oxidized
end
def resolve_auth opt
- # Resolve configured username/password, give priority to group level configuration
- # TODO: refactor to use revised behaviour of Asetus
- cfg_username, cfg_password =
- if Oxidized.config.groups.has_key?(@group) and ['username', 'password'].all? {|e| Oxidized.config.groups[@group].has_key?(e)}
- [Oxidized.config.groups[@group].username, Oxidized.config.groups[@group].password]
- elsif ['username', 'password'].all? {|e| Oxidized.config.has_key?(e)}
- [Oxidized.config.username, Oxidized.config.password]
- else
- [nil, nil]
- end
- auth = {}
- auth[:username] = (opt[:username] or cfg_username)
- auth[:password] = (opt[:password] or cfg_password)
- auth
+ # Resolve configured username/password
+ {
+ username: resolve_key(:username, opt),
+ password: resolve_key(:password, opt),
+ }
end
def resolve_input opt
- inputs = (opt[:input] or Oxidized.config.input.default)
+ inputs = resolve_key :input, opt, Oxidized.config.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}"
@@ -157,7 +146,7 @@ module Oxidized
end
def resolve_output opt
- output = (opt[:output] or Oxidized.config.output.default)
+ output = resolve_key :output, opt, Oxidized.config.output.default
if not Oxidized.mgr.output[output]
Oxidized.mgr.add_output output or raise MethodNotFound, "#{output} not found for node #{ip}"
end
@@ -165,7 +154,7 @@ module Oxidized
end
def resolve_model opt
- model = (opt[:model] or Oxidized.config.model)
+ model = resolve_key :model, opt
if not Oxidized.mgr.model[model]
Oxidized.logger.debug "lib/oxidized/node.rb: Loading model #{model.inspect}"
Oxidized.mgr.add_model model or raise ModelNotFound, "#{model} not found for node #{ip}"
@@ -173,15 +162,52 @@ module Oxidized
Oxidized.mgr.model[model].new
end
- def resolve_repo
+ def resolve_repo opt
+ return unless is_git? opt
+
remote_repo = Oxidized.config.output.git.repo
- if Oxidized.config.output.git.single_repo? || @group.nil? || remote_repo.is_a?(String)
- remote_repo
+ if remote_repo.is_a?(::String)
+ if Oxidized.config.output.git.single_repo? || @group.nil?
+ remote_repo
+ else
+ File.join(File.dirname(remote_repo), @group + '.git')
+ end
else
remote_repo[@group]
end
end
+ def resolve_key key, opt, global=nil
+ # resolve key, first get global, then get group then get node config
+ key_sym = key.to_sym
+ key_str = key.to_s
+ value = global
+ Oxidized.logger.debug "node.rb: resolving node key '#{key}', with passed global value of '#{value}' and node value '#{opt[key_sym]}'"
+
+ #global
+ if not value and Oxidized.config.has_key?(key_str)
+ value = Oxidized.config[key_str]
+ Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '#{value}' from global"
+ end
+
+ #group
+ if Oxidized.config.groups.has_key?(@group)
+ if Oxidized.config.groups[@group].has_key?(key_str)
+ value = Oxidized.config.groups[@group][key_str]
+ Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '#{value}' from group"
+ end
+ end
+
+ #node
+ value = opt[key_sym] || value
+ Oxidized.logger.debug "node.rb: returning node key '#{key}' with value '#{value}'"
+ value
+ end
+
+ def is_git? opt
+ (opt[:output] || Oxidized.config.output.default) == 'git'
+ end
+
end
end
diff --git a/lib/oxidized/nodes.rb b/lib/oxidized/nodes.rb
index cd67007..f5a1ad0 100644
--- a/lib/oxidized/nodes.rb
+++ b/lib/oxidized/nodes.rb
@@ -56,11 +56,8 @@ module Oxidized
end
end
- def fetch node, group
- with_lock do
- i = find_node_index node
- output = self[i].output.new
- raise Oxidized::NotSupported unless output.respond_to? :fetch
+ def fetch node_name, group
+ yield_node_output(node_name) do |node, output|
output.fetch node, group
end
end
@@ -94,6 +91,24 @@ module Oxidized
find_index node or raise Oxidized::NodeNotFound, "unable to find '#{node}'"
end
+ def version node_name, group
+ yield_node_output(node_name) do |node, output|
+ output.version node, group
+ end
+ end
+
+ def get_version node_name, group, oid
+ yield_node_output(node_name) do |node, output|
+ output.get_version node, group, oid
+ end
+ end
+
+ def get_diff node_name, group, oid1, oid2
+ yield_node_output(node_name) do |node, output|
+ output.get_diff node, group, oid1, oid2
+ end
+ end
+
private
def initialize opts={}
@@ -151,34 +166,13 @@ module Oxidized
sort_by! { |x| x.last.nil? ? Time.new(0) : x.last.end }
end
- public
-
- def version node, group
+ def yield_node_output(node_name)
with_lock do
- i = find_node_index node
- output = self[i].output.new
+ node = find { |n| n.name == node_name }
+ output = node.output.new
raise Oxidized::NotSupported unless output.respond_to? :fetch
- output.version node, group
- end
- end
-
- def get_version node, group, oid
- with_lock do
- i = find_node_index node
- output = self[i].output.new
- raise Oxidized::NotSupported unless output.respond_to? :fetch
- output.get_version node, group, oid
+ yield node, output
end
end
-
- def get_diff node, group, oid1, oid2
- with_lock do
- i = find_node_index node
- output = self[i].output.new
- raise Oxidized::NotSupported unless output.respond_to? :fetch
- output.get_diff node, group, oid1, oid2
- end
- end
-
end
end
diff --git a/lib/oxidized/output/file.rb b/lib/oxidized/output/file.rb
index bb13827..0b64447 100644
--- a/lib/oxidized/output/file.rb
+++ b/lib/oxidized/output/file.rb
@@ -17,7 +17,7 @@ class OxidizedFile < Output
end
def store node, outputs, opt={}
- file = @cfg.directory
+ file = File.expand_path @cfg.directory
if opt[:group]
file = File.join File.dirname(file), opt[:group]
end
@@ -28,7 +28,7 @@ class OxidizedFile < Output
end
def fetch node, group
- cfg_dir = @cfg.directory
+ cfg_dir = File.expand_path @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 8d9dae1..fee0ab6 100644
--- a/lib/oxidized/output/git.rb
+++ b/lib/oxidized/output/git.rb
@@ -41,7 +41,7 @@ class Git < Output
outputs.types.each do |type|
type_cfg = ''
- type_repo = File.join File.dirname(repo), type + '.git'
+ type_repo = File.join(File.dirname(repo), type + '.git')
outputs.type(type).each do |output|
(type_cfg << output; next) if not output.name
type_file = file + '--' + output.name
@@ -60,29 +60,21 @@ class Git < Output
def fetch node, group
begin
- repo = @cfg.repo
- repo = File.join File.dirname(repo), group + '.git' if group and not @cfg.single_repo?
+ repo, path = yield_repo_and_path(node, group)
repo = Rugged::Repository.new repo
index = repo.index
index.read_tree repo.head.target.tree unless repo.empty?
- file = node
- file = File.join(group, node) if group and @cfg.single_repo?
- repo.read(index.get(file)[:oid]).data
+ repo.read(index.get(path)[:oid]).data
rescue
'node not found'
end
end
- #give a hash of all oid revision for the given node, and the date of the commit
+ # give a hash of all oid revision for the given node, and the date of the commit
def version node, group
begin
- repo = @cfg.repo
- path = node
- if group and @cfg.single_repo?
- path = "#{group}/#{node}"
- elsif group
- repo = File.join File.dirname(repo), group + '.git'
- end
+ repo, path = yield_repo_and_path(node, group)
+
repo = Rugged::Repository.new repo
walker = Rugged::Walker.new(repo)
walker.sorting(Rugged::SORT_DATE)
@@ -109,14 +101,9 @@ class Git < Output
#give the blob of a specific revision
def get_version node, group, oid
begin
- repo = @cfg.repo
- if group && group != '' && !@cfg.single_repo?
- repo = File.join File.dirname(repo), group + '.git'
- elsif group && group != ''
- node = File.join group, node
- end
+ repo, path = yield_repo_and_path(node, group)
repo = Rugged::Repository.new repo
- repo.blob_at(oid,node).content
+ repo.blob_at(oid,path).content
rescue
'version not found'
end
@@ -125,30 +112,27 @@ class Git < Output
#give a hash with the patch of a diff between 2 revision and the stats (added and deleted lines)
def get_diff node, group, oid1, oid2
begin
- repo = @cfg.repo
diff_commits = nil
- if group && group != '' && !@cfg.single_repo?
- repo = File.join File.dirname(repo), group + '.git'
- end
+ repo, _ = yield_repo_and_path(node, group)
repo = Rugged::Repository.new repo
commit = repo.lookup(oid1)
- #if the second revision is precised
+
if oid2
commit_old = repo.lookup(oid2)
diff = repo.diff(commit_old, commit)
diff.each do |patch|
- if /#{node}\s+/.match(patch.to_s.lines.first)
+ if /#{node.name}\s+/.match(patch.to_s.lines.first)
diff_commits = {:patch => patch.to_s, :stat => patch.stat}
break
end
end
- #else gives the diffs between the first oid and his first parrent
else
stat = commit.parents[0].diff(commit).stat
stat = [stat[1],stat[2]]
patch = commit.parents[0].diff(commit).patch
diff_commits = {:patch => patch, :stat => stat}
end
+
diff_commits
rescue
'no diffs'
@@ -157,6 +141,16 @@ class Git < Output
private
+ def yield_repo_and_path(node, group)
+ repo, path = node.repo, node.name
+
+ if group and @cfg.single_repo?
+ path = "#{group}/#{node.name}"
+ end
+
+ [repo, path]
+ end
+
def update repo, file, data
return if data.empty?
diff --git a/lib/oxidized/version.rb b/lib/oxidized/version.rb
index 428cd19..54defae 100644
--- a/lib/oxidized/version.rb
+++ b/lib/oxidized/version.rb
@@ -1,3 +1,3 @@
module Oxidized
- VERSION = '0.14.3'
+ VERSION = '0.16.3'
end
diff --git a/oxidized.gemspec b/oxidized.gemspec
index 9ff795c..bb9366d 100644
--- a/oxidized.gemspec
+++ b/oxidized.gemspec
@@ -23,6 +23,11 @@ Gem::Specification.new do |s|
s.add_runtime_dependency 'slop', '~> 3.5'
s.add_runtime_dependency 'net-ssh', '>= 3.0.0', '<3.1'
s.add_runtime_dependency 'rugged', '~> 0.21', '>= 0.21.4'
+
+ if defined?(RUBY_VERSION) && RUBY_VERSION > '2.3'
+ s.add_runtime_dependency 'net-telnet'
+ end
+
s.add_development_dependency 'pry', '~> 0'
s.add_development_dependency 'bundler', '~> 1.10'
s.add_development_dependency 'rake', '~> 10.0'
diff --git a/spec/githubrepo_spec.rb b/spec/githubrepo_spec.rb
index ab5e251..2f84c78 100644
--- a/spec/githubrepo_spec.rb
+++ b/spec/githubrepo_spec.rb
@@ -10,10 +10,11 @@ describe GithubRepo do
let(:repo) { mock() }
let(:gr) { GithubRepo.new }
- before(:each) do
+ before do
Oxidized.asetus = Asetus.new
Oxidized.config.log = '/dev/null'
Oxidized.setup_logger
+ Oxidized.config.output.default = 'git'
end
describe '#validate_cfg!' do
@@ -84,23 +85,23 @@ describe GithubRepo do
let(:group) { nil }
let(:ctx) { OpenStruct.new(node: node) }
let(:node) do
- Oxidized::Node.new(ip: '127.0.0.1', group: group, model: 'junos', output: 'output')
+ Oxidized::Node.new(ip: '127.0.0.1', group: group, model: 'junos', output: 'git')
end
before do
repo_head.expects(:name).twice.returns('refs/heads/master')
repo.expects(:head).twice.returns(repo_head)
- repo.expects(:path).returns('foo.git')
+ repo.expects(:path).returns('/foo.git')
repo.expects(:fetch).with('origin', ['refs/heads/master'], credentials: credentials).returns(Hash.new(0))
end
describe 'when there is only one repository and no groups' do
before do
- Oxidized.config.output.git.repo = 'foo.git'
+ Oxidized.config.output.git.repo = '/foo.git'
remote.expects(:url).returns('https://github.com/username/foo.git')
remote.expects(:push).with(['refs/heads/master'], credentials: credentials).returns(true)
repo.expects(:remotes).returns({'origin' => remote})
- Rugged::Repository.expects(:new).with('foo.git').returns(repo)
+ Rugged::Repository.expects(:new).with('/foo.git').returns(repo)
end
it "will push to the remote repository using https" do
@@ -136,7 +137,7 @@ describe GithubRepo do
describe 'and there are several repositories' do
let(:create_remote) { 'ggrroouupp#remote_repo' }
- let(:repository) { './ggrroouupp.git' }
+ let(:repository) { '/ggrroouupp.git' }
before do
Oxidized.config.output.git.repo.ggrroouupp = repository
@@ -151,7 +152,7 @@ describe GithubRepo do
describe 'and has a single repository' do
let(:create_remote) { 'github_repo_hook#remote_repo' }
- let(:repository) { 'foo.git' }
+ let(:repository) { '/foo.git' }
before do
Oxidized.config.output.git.repo = repository
diff --git a/spec/input/ssh_spec.rb b/spec/input/ssh_spec.rb
index 2550d5c..d86ffa0 100644
--- a/spec/input/ssh_spec.rb
+++ b/spec/input/ssh_spec.rb
@@ -5,6 +5,7 @@ describe Oxidized::SSH do
before(:each) do
Oxidized.asetus = Asetus.new
Oxidized.setup_logger
+ Oxidized::Node.any_instance.stubs(:resolve_repo)
Oxidized::Node.any_instance.stubs(:resolve_input)
Oxidized::Node.any_instance.stubs(:resolve_output)
@node = Oxidized::Node.new(name: 'example.com',
diff --git a/spec/node_spec.rb b/spec/node_spec.rb
index 1c38558..829e05a 100644
--- a/spec/node_spec.rb
+++ b/spec/node_spec.rb
@@ -5,6 +5,7 @@ describe Oxidized::Node do
Oxidized.asetus = Asetus.new
Oxidized.setup_logger
+ Oxidized::Node.any_instance.stubs(:resolve_repo)
Oxidized::Node.any_instance.stubs(:resolve_output)
@node = Oxidized::Node.new(name: 'example.com',
input: 'ssh',
@@ -44,6 +45,11 @@ describe Oxidized::Node do
end
describe '#repo' do
+ before do
+ Oxidized.config.output.default = 'git'
+ Oxidized::Node.any_instance.unstub(:resolve_repo)
+ end
+
let(:group) { nil }
let(:node) do
Oxidized::Node.new({
diff --git a/spec/nodes_spec.rb b/spec/nodes_spec.rb
index 4560bdb..6fa4b41 100644
--- a/spec/nodes_spec.rb
+++ b/spec/nodes_spec.rb
@@ -15,6 +15,7 @@ describe Oxidized::Nodes do
prompt: 'test_prompt'
}
+ Oxidized::Node.any_instance.stubs(:resolve_repo)
Oxidized::Node.any_instance.stubs(:resolve_output)
@nodes_org = %w(ltt-pe1.hel kes2-rr1.tku tor-peer1.oul
hal-p2.tre sav-gr1-sw1.kuo psl-sec-pe1.hel).map { |e| Oxidized::Node.new(opts.merge(name: e)) }