diff options
| author | Elvin Efendi <elvin.efendiyev@gmail.com> | 2016-01-04 10:22:00 -0500 | 
|---|---|---|
| committer | Elvin Efendi <elvin.efendiyev@gmail.com> | 2016-01-04 10:22:00 -0500 | 
| commit | db5545d760a5baad052370504dd03585ac6f3215 (patch) | |
| tree | 1c8923703da25cbc56ad3dea2b59d639c39a5b22 | |
| parent | ef1a59d2b29df5b00246ee34eba96b0cf4927fa2 (diff) | |
| parent | f112dfa0c604ae1c990f6411a002806924c00bf3 (diff) | |
Merge remote-tracking branch 'upstream/master' into merge-upstream
| -rw-r--r-- | CHANGELOG.md | 5 | ||||
| -rw-r--r-- | README.md | 95 | ||||
| -rw-r--r-- | extra/nagios_check_failing_nodes.rb | 8 | ||||
| -rwxr-xr-x | extra/oxidized-report-git-commits | 80 | ||||
| -rw-r--r-- | extra/rvm.oxidized.upstart | 18 | ||||
| -rw-r--r-- | lib/oxidized/config/vars.rb | 9 | ||||
| -rw-r--r-- | lib/oxidized/hook/exec.rb | 2 | ||||
| -rw-r--r-- | lib/oxidized/model/fortios.rb | 2 | ||||
| -rw-r--r-- | lib/oxidized/model/nos.rb | 2 | ||||
| -rw-r--r-- | lib/oxidized/model/powerconnect.rb | 17 | ||||
| -rw-r--r-- | lib/oxidized/model/saos.rb | 24 | ||||
| -rw-r--r-- | lib/oxidized/node.rb | 6 | ||||
| -rw-r--r-- | lib/oxidized/output/file.rb | 12 | ||||
| -rw-r--r-- | lib/oxidized/output/git.rb | 7 | ||||
| -rw-r--r-- | lib/oxidized/worker.rb | 6 | ||||
| -rw-r--r-- | oxidized.gemspec | 6 | 
16 files changed, 246 insertions, 53 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 @@ -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/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/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..127a2de 100644 --- a/oxidized.gemspec +++ b/oxidized.gemspec @@ -5,7 +5,11 @@ require 'oxidized/version'  Gem::Specification.new do |s|    s.name              = 'oxidized' +<<<<<<< HEAD    s.version           = Oxidized::VERSION +======= +  s.version           = '0.9.0' +>>>>>>> upstream/master    s.licenses          = %w( Apache-2.0 )    s.platform          = Gem::Platform::RUBY    s.authors           = [ 'Saku Ytti', 'Samer Abdel-Hafez', 'Anton Aksola' ] @@ -21,7 +25,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', '~> 2.9', '>= 2.9.3'    s.add_runtime_dependency 'rugged',  '~> 0.21', '>= 0.21.4'    s.add_development_dependency 'pry', '~> 0'    s.add_development_dependency 'bundler', '~> 1.10' | 
