diff options
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 @@ -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)) } |