summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md5
-rw-r--r--Gemfile.lock10
-rw-r--r--README.md95
-rw-r--r--Rakefile35
-rw-r--r--extra/nagios_check_failing_nodes.rb8
-rwxr-xr-xextra/oxidized-report-git-commits80
-rw-r--r--extra/rvm.oxidized.upstart18
-rw-r--r--lib/oxidized/config/vars.rb9
-rw-r--r--lib/oxidized/hook/exec.rb2
-rw-r--r--lib/oxidized/model/fortios.rb2
-rw-r--r--lib/oxidized/model/nos.rb2
-rw-r--r--lib/oxidized/model/powerconnect.rb17
-rw-r--r--lib/oxidized/model/saos.rb24
-rw-r--r--lib/oxidized/node.rb6
-rw-r--r--lib/oxidized/output/file.rb12
-rw-r--r--lib/oxidized/output/git.rb7
-rw-r--r--lib/oxidized/version.rb2
-rw-r--r--lib/oxidized/worker.rb6
-rw-r--r--oxidized.gemspec2
19 files changed, 283 insertions, 59 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bf3d8d5..d123b46 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+# 0.9.0
+- FEATURE: input log now uses devices name as file, instead of string from config (by @skoef)
+- FEATURE: Dell Networkign OS (dnos) support (by @erefre)
+- BUGFIX: CiscoSMB, powerconnect, comware, xos, ironware, nos fixes
+
# 0.8.1
- BUGFIX: restore ruby 1.9.3 compatibility
diff --git a/Gemfile.lock b/Gemfile.lock
index bbdc4c8..b46ca2f 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,9 +1,9 @@
PATH
remote: .
specs:
- oxidized (0.8.1)
+ oxidized (0.9.0)
asetus (~> 0.1)
- net-ssh (~> 2.8)
+ net-ssh (~> 3.0, >= 3.0.2)
rugged (~> 0.21, >= 0.21.4)
slop (~> 3.5)
@@ -14,10 +14,10 @@ GEM
coderay (1.1.0)
metaclass (0.0.4)
method_source (0.8.2)
- minitest (5.8.2)
+ minitest (5.8.3)
mocha (1.1.0)
metaclass (~> 0.0.1)
- net-ssh (2.9.2)
+ net-ssh (3.0.2)
pry (0.10.3)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
@@ -38,4 +38,4 @@ DEPENDENCIES
rake (~> 10.0)
BUNDLED WITH
- 1.10.6
+ 1.11.2
diff --git a/README.md b/README.md
index 3b7083f..b5cd435 100644
--- a/README.md
+++ b/README.md
@@ -42,39 +42,66 @@ Oxidized is a network device configuration backup tool. It's a RANCID replacemen
# Supported OS types
- * A10 Networks ACOS
- * Alcatel-Lucent ISAM 7302/7330
- * Alcatel-Lucent Operating System AOS
- * Alcatel-Lucent Operating System AOS7
- * Alcatel-Lucent Operating System Wireless
- * Alcatel-Lucent TiMOS
- * Arista EOS
- * Brocade Fabric OS
- * Brocade Ironware
- * Brocade NOS (Network Operating System)
- * Brocade Vyatta
- * Cisco AireOS
- * Cisco ASA
- * Cisco IOS
- * Cisco IOS-XR
- * Cisco NXOS
- * Cisco SMB (Nikola series)
- * Cumulus Linux
- * DELL PowerConnect
- * Extreme Networks XOS
- * Force10 FTOS
- * Force10 NDOS
- * FortiGate FortiOS
- * HP Comware (HP A-series, H3C, 3Com)
- * HP ProCurve
- * Huawei VRP
- * Juniper JunOS
- * Juniper ScreenOS (Netscreen)
- * Mikrotik RouterOS
- * MRV Master-OS
- * Ubiquiti AirOS
- * Palo Alto PAN-OS
- * Zyxel ZyNOS
+ * A10 Networks
+ * ACOS
+ * Alcatel-Lucent
+ * ISAM
+ * AOS
+ * AOS7
+ * Wireless
+ * TiMOS
+ * Arista
+ * EOS
+ * Arris
+ * C4CMTS
+ * Aruba
+ * AOSW
+ * Brocade
+ * FabricOS
+ * Ironware
+ * NOS (Network Operating System)
+ * Vyatta
+ * Ciena
+ * SOAS
+ * Cisco
+ * AireOS
+ * ASA
+ * IOS
+ * IOSXR
+ * NXOS
+ * SMB (Nikola series)
+ * Cumulus
+ * Linux
+ * DELL
+ * PowerConnect
+ * AOSW
+ * Extreme Networks
+ * XOS
+ * Force10
+ * FTOS
+ * Force10
+ * DNOS
+ * FortiGate
+ * FortiOS
+ * HP
+ * Comware (HP A-series, H3C, 3Com)
+ * Procurve
+ * Huawei
+ * VRP
+ * Juniper
+ * JunOS
+ * ScreenOS (Netscreen)
+ * Mikrotik
+ * RouterOS
+ * MRV
+ * MasterOS
+ * Ubiquiti
+ * AirOS
+ * Edgeos
+ * Palo Alto
+ * PANOS
+ * Zyxel
+ * ZyNOS
# Installation
@@ -444,6 +471,8 @@ OX_NODE_MSG
OX_NODE_GROUP
OX_JOB_STATUS
OX_JOB_TIME
+OX_REPO_COMMITREF
+OX_REPO_NAME
```
Exec hook recognizes following configuration keys:
diff --git a/Rakefile b/Rakefile
index 2dc5415..3a1be5e 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,6 +1,14 @@
require 'bundler/gem_tasks'
require 'rake/testtask'
+gemspec = eval(File.read(Dir['*.gemspec'].first))
+file = [gemspec.name, gemspec.version].join('-') + '.gem'
+
+desc 'Validate gemspec'
+task :gemspec do
+ gemspec.validate
+end
+
desc 'Run minitest'
task :test do
Rake::TestTask.new do |t|
@@ -11,4 +19,31 @@ task :test do
end
end
+desc 'Build gem'
+task :build do
+ system "gem build #{gemspec.name}.gemspec"
+ FileUtils.mkdir_p 'gems'
+ FileUtils.mv file, 'gems'
+end
+
+desc 'Install gem'
+task :install => :build do
+ system "sudo -Es sh -c \'umask 022; gem install gems/#{file}\'"
+end
+
+desc 'Remove gems'
+task :clean do
+ FileUtils.rm_rf 'gems'
+end
+
+desc 'Tag the release'
+task :tag do
+ system "git tag #{gemspec.version}"
+end
+
+desc 'Push to rubygems'
+task :push => :tag do
+ system "gem push gems/#{file}"
+end
+
task default: :test
diff --git a/extra/nagios_check_failing_nodes.rb b/extra/nagios_check_failing_nodes.rb
index 27a5c66..abb34ba 100644
--- a/extra/nagios_check_failing_nodes.rb
+++ b/extra/nagios_check_failing_nodes.rb
@@ -23,12 +23,12 @@ json.each do |node|
end
end
-if pending
- puts '[WARN] Pending backup: ' + pending_nodes.join(',')
- exit 1
-elsif critical
+if critical
puts '[CRIT] Unable to backup: ' + critical_nodes.join(',')
exit 2
+elsif pending
+ puts '[WARN] Pending backup: ' + pending_nodes.join(',')
+ exit 1
else
puts '[OK] Backup of all nodes completed successfully.'
exit 0
diff --git a/extra/oxidized-report-git-commits b/extra/oxidized-report-git-commits
new file mode 100755
index 0000000..2b1a2d7
--- /dev/null
+++ b/extra/oxidized-report-git-commits
@@ -0,0 +1,80 @@
+#!/bin/sh
+#
+# A script to maintain a local working copy of an oxidized configuration
+# repository and mail out diffs for configuration changes
+#
+# Copyright 2016 Nick Hilliard <nick@foobar.org>, All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# usage: add the following hook to the oxidized config file:
+#
+# hooks:
+# email_output:
+# type: exec
+# events: [post_store, node_fail]
+# cmd: 'update-local-repo.sh ~/gitdir/ | mail -s "Oxidized updates for ${OX_NODE_NAME}" update-recipient@example.com'
+# async: true
+# timeout: 120
+#
+#
+# The script takes a single argument, namely a git working directory name,
+# e.g. "~/gitdir/". This is only used as a staging directory and should
+# not be set to be the same as the git repo directory.
+#
+
+PATH=${PATH}:/usr/local/bin:/usr/local/sbin
+export PATH
+
+gitdir=$1
+
+if [ X${OX_REPO_COMMITREF} = "X" ]; then
+ echo \$OX_REPO_COMMITREF not set
+ exit 64
+fi
+
+if [ X${OX_REPO_NAME} = "X" ]; then
+ echo \$OX_REPO_NAME not set
+ exit 64
+fi
+
+if [ ! -d ${gitdir}/.git ]; then
+ git clone -q ${OX_REPO_NAME} ${gitdir}
+
+ ret=$?
+ if [ X"${ret}" != X0 ] && [ X"${ret}" != X1 ]; then
+ echo git clone failed: aborting.
+ exit 128
+ fi
+fi
+
+cd ${gitdir}
+
+git pull -q > /dev/null 2>&1
+ret=$?
+if [ X"${ret}" != X0 ] && [ X"${ret}" != X1 ]; then
+ echo git pull failed: aborting.
+ exit 128
+fi
+
+# Git is probably working at this stage, so safe to emit more info
+
+echo "Node name: ${OX_NODE_NAME}"
+echo "Group Name: ${OX_NODE_GROUP}"
+echo "Job Time: ${OX_JOB_TIME}"
+echo "Git Commit ID: ${OX_REPO_COMMITREF}"
+echo "Git Repo: ${OX_REPO_NAME}"
+echo "Local working dir: ${gitdir}"
+echo ""
+
+git diff --no-color ${OX_REPO_COMMITREF}~1..${OX_REPO_COMMITREF}
diff --git a/extra/rvm.oxidized.upstart b/extra/rvm.oxidized.upstart
new file mode 100644
index 0000000..23b5d69
--- /dev/null
+++ b/extra/rvm.oxidized.upstart
@@ -0,0 +1,18 @@
+start on started networking
+
+respawn
+
+setuid oxidized
+setgid oxidized
+
+chdir /home/oxidized
+
+env HOME=/home/oxidized
+
+pre-start script
+ test -x /usr/local/rvm/wrappers/ruby-2.1.2/oxidized || { stop; exit 0; }
+end script
+
+script
+ exec /usr/local/rvm/wrappers/ruby-2.1.2/oxidized
+end script \ No newline at end of file
diff --git a/lib/oxidized/config/vars.rb b/lib/oxidized/config/vars.rb
index 10f39c3..09f9781 100644
--- a/lib/oxidized/config/vars.rb
+++ b/lib/oxidized/config/vars.rb
@@ -2,9 +2,14 @@ module Oxidized::Config::Vars
# convenience method for accessing node, group or global level user variables
# nil values will be ignored
def vars name
- r = @node.vars[name] unless @node.vars.nil?
- r ||= Oxidized.config.groups[@node.group].vars[name.to_s] if Oxidized.config.groups.has_key?(@node.group)
+ r = @node.vars[name] unless @node.vars.nil?
+ if Oxidized.config.groups.has_key?(@node.group)
+ if Oxidized.config.groups[@node.group].vars.has_key?(name.to_s)
+ r ||= Oxidized.config.groups[@node.group].vars[name.to_s]
+ end
+ end
r ||= Oxidized.config.vars[name.to_s] if Oxidized.config.vars.has_key?(name.to_s)
r
end
end
+
diff --git a/lib/oxidized/hook/exec.rb b/lib/oxidized/hook/exec.rb
index af2aeb1..58d6fd5 100644
--- a/lib/oxidized/hook/exec.rb
+++ b/lib/oxidized/hook/exec.rb
@@ -71,6 +71,8 @@ class Exec < Oxidized::Hook
"OX_NODE_MSG" => ctx.node.msg.to_s,
"OX_NODE_GROUP" => ctx.node.group.to_s,
"OX_EVENT" => ctx.event.to_s,
+ "OX_REPO_COMMITREF" => ctx.commitref.to_s,
+ "OX_REPO_NAME" => ctx.node.repo.to_s,
)
end
if ctx.job
diff --git a/lib/oxidized/model/fortios.rb b/lib/oxidized/model/fortios.rb
index 2c796cb..a9d219c 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?)$/
cmd :all do |cfg, cmdstring|
new_cfg = comment "COMMAND: #{cmdstring}\n"
diff --git a/lib/oxidized/model/nos.rb b/lib/oxidized/model/nos.rb
index c2f4319..18ca6a2 100644
--- a/lib/oxidized/model/nos.rb
+++ b/lib/oxidized/model/nos.rb
@@ -26,7 +26,7 @@ class NOS < Oxidized::Model
end
cfg 'show system' do |cfg|
- commen cfg.each_line.reject { |line| line.match /Time/ or line.match /speed/ }
+ comment cfg.each_line.reject { |line| line.match /Time/ or line.match /speed/ }
end
cmd 'show running-config'
diff --git a/lib/oxidized/model/powerconnect.rb b/lib/oxidized/model/powerconnect.rb
index ec15402..cd04766 100644
--- a/lib/oxidized/model/powerconnect.rb
+++ b/lib/oxidized/model/powerconnect.rb
@@ -14,6 +14,9 @@ class PowerConnect < Oxidized::Model
end
cmd 'show version' do |cfg|
+ if (@stackable.nil?)
+ @stackable = true if cfg.match /(U|u)nit\s/
+ end
cfg = cfg.split("\n").select { |line| not line[/Up\sTime/] }
comment cfg.join("\n") + "\n"
end
@@ -47,15 +50,17 @@ class PowerConnect < Oxidized::Model
def clean cfg
out = []
- skip_block = false
+ skip_blocks = 0
cfg.each_line do |line|
- if line.match /Up\sTime|Temperature|Power Supplies/i
- # For 34xx, 35xx, 54xx, 55xx, 62xx and 8024F we should skip this block (terminated by a blank line)
- skip_block = true if @model =~ /^(34|35)(24|48)$|^(54|55)(24|48)$|^(62)(24|48)$|^8024$/
+ # If this is a stackable switch we should skip this block of information
+ if (line.match /Up\sTime|Temperature|Power Suppl(ies|y)|Fans/i and @stackable == true)
+ skip_blocks = 1
+ # Some switches have another empty line. This is identified by this line having a colon
+ skip_blocks = 2 if line.match /:/
end
# If we have lines to skip do this until we reach and empty line
- if skip_block
- skip_block = false if /\S/ !~ line
+ if skip_blocks > 0
+ skip_blocks -= 1 if /\S/ !~ line
next
end
out << line.strip
diff --git a/lib/oxidized/model/saos.rb b/lib/oxidized/model/saos.rb
new file mode 100644
index 0000000..cada35b
--- /dev/null
+++ b/lib/oxidized/model/saos.rb
@@ -0,0 +1,24 @@
+class SAOS < Oxidized::Model
+
+ # Ciena SAOS switch
+ # used for 6.x devices
+
+ comment '! '
+
+ cmd :all do |cfg|
+ cfg.each_line.to_a[1..-2].join
+ end
+
+ cmd 'configuration show' do |cfg|
+ cfg
+ end
+
+ cfg :telnet do
+ username /login:/
+ password /assword:/
+ end
+ cfg :telnet do
+ post_login 'system shell session set more off'
+ pre_logout 'exit'
+ end
+end \ No newline at end of file
diff --git a/lib/oxidized/node.rb b/lib/oxidized/node.rb
index c16e3d0..7a278a9 100644
--- a/lib/oxidized/node.rb
+++ b/lib/oxidized/node.rb
@@ -5,10 +5,13 @@ module Oxidized
class MethodNotFound < OxidizedError; end
class ModelNotFound < OxidizedError; end
class Node
- attr_reader :name, :ip, :model, :input, :output, :group, :auth, :prompt, :vars, :last
+ attr_reader :name, :ip, :model, :input, :output, :group, :auth, :prompt, :vars, :last, :repo
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
@name = opt[:name]
@ip = IPAddr.new(opt[:ip]).to_s rescue nil
@ip ||= Resolv.new.getaddress @name
@@ -21,6 +24,7 @@ module Oxidized
@vars = opt[:vars]
@stats = Stats.new
@retry = 0
+ @repo = Oxidized.config.output.git.repo
# model instance needs to access node instance
@model.node = self
diff --git a/lib/oxidized/output/file.rb b/lib/oxidized/output/file.rb
index ba08683..bb13827 100644
--- a/lib/oxidized/output/file.rb
+++ b/lib/oxidized/output/file.rb
@@ -2,6 +2,8 @@ module Oxidized
class OxidizedFile < Output
require 'fileutils'
+ attr_reader :commitref
+
def initialize
@cfg = Oxidized.config.output.file
end
@@ -22,6 +24,7 @@ class OxidizedFile < Output
FileUtils.mkdir_p file
file = File.join file, node
open(file, 'w') { |fh| fh.write outputs.to_cfg }
+ @commitref = file
end
def fetch node, group
@@ -39,5 +42,14 @@ class OxidizedFile < Output
end
end
+ def version node, group
+ # not supported
+ []
+ end
+
+ def get_version node, group, oid
+ 'not supported'
+ end
+
end
end
diff --git a/lib/oxidized/output/git.rb b/lib/oxidized/output/git.rb
index eedf51d..8b605f6 100644
--- a/lib/oxidized/output/git.rb
+++ b/lib/oxidized/output/git.rb
@@ -7,6 +7,8 @@ class Git < Output
raise OxidizedError, 'rugged not found: sudo gem install rugged'
end
+ attr_reader :commitref
+
def initialize
@cfg = Oxidized.config.output.git
end
@@ -27,6 +29,7 @@ class Git < Output
@user = (opt[:user] or @cfg.user)
@email = (opt[:email] or @cfg.email)
@opt = opt
+ @commitref = nil
repo = @cfg.repo
outputs.types.each do |type|
@@ -63,7 +66,7 @@ class Git < Output
end
end
- #give a hash of all oid revision for the givin 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
@@ -176,7 +179,7 @@ class Git < Output
if tree_old != tree_new
repo.config['user.name'] = user
repo.config['user.email'] = email
- Rugged::Commit.create(repo,
+ @commitref = Rugged::Commit.create(repo,
:tree => index.write_tree(repo),
:message => msg,
:parents => repo.empty? ? [] : [repo.head.target].compact,
diff --git a/lib/oxidized/version.rb b/lib/oxidized/version.rb
index c2a0c0e..38772b7 100644
--- a/lib/oxidized/version.rb
+++ b/lib/oxidized/version.rb
@@ -1,3 +1,3 @@
module Oxidized
- VERSION = '0.8.1'
+ VERSION = '0.9.0'
end
diff --git a/lib/oxidized/worker.rb b/lib/oxidized/worker.rb
index 15977e2..324dcb5 100644
--- a/lib/oxidized/worker.rb
+++ b/lib/oxidized/worker.rb
@@ -39,11 +39,13 @@ module Oxidized
msg = "update #{node.name}"
msg += " from #{node.from}" if node.from
msg += " with message '#{node.msg}'" if node.msg
- if node.output.new.store node.name, job.config,
+ output = node.output.new
+ if output.store node.name, job.config,
:msg => msg, :user => node.user, :group => node.group
Oxidized.logger.info "Configuration updated for #{node.group}/#{node.name}"
Oxidized.Hooks.handle :post_store, :node => node,
- :job => job
+ :job => job,
+ :commitref => output.commitref
end
node.reset
else
diff --git a/oxidized.gemspec b/oxidized.gemspec
index a5d481e..808d508 100644
--- a/oxidized.gemspec
+++ b/oxidized.gemspec
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
s.required_ruby_version = '>= 1.9.3'
s.add_runtime_dependency 'asetus', '~> 0.1'
s.add_runtime_dependency 'slop', '~> 3.5'
- s.add_runtime_dependency 'net-ssh', '~> 2.8'
+ s.add_runtime_dependency 'net-ssh', '~> 3.0', '>= 3.0.2'
s.add_runtime_dependency 'rugged', '~> 0.21', '>= 0.21.4'
s.add_development_dependency 'pry', '~> 0'
s.add_development_dependency 'bundler', '~> 1.10'