summaryrefslogtreecommitdiff
path: root/lib/oxidized
diff options
context:
space:
mode:
Diffstat (limited to 'lib/oxidized')
-rw-r--r--lib/oxidized/config.rb5
-rw-r--r--lib/oxidized/hook/slackdiff.rb34
-rw-r--r--lib/oxidized/input/ssh.rb5
-rw-r--r--lib/oxidized/model/aireos.rb2
-rw-r--r--lib/oxidized/model/airos.rb13
-rw-r--r--lib/oxidized/model/alvarion.rb4
-rw-r--r--lib/oxidized/model/aosw.rb28
-rw-r--r--lib/oxidized/model/asa.rb5
-rw-r--r--lib/oxidized/model/cisconga.rb19
-rw-r--r--lib/oxidized/model/comware.rb6
-rw-r--r--lib/oxidized/model/cumulus.rb18
-rw-r--r--lib/oxidized/model/firewareos.rb8
-rw-r--r--lib/oxidized/model/fortios.rb16
-rw-r--r--lib/oxidized/model/ios.rb87
-rw-r--r--lib/oxidized/model/ironware.rb2
-rw-r--r--lib/oxidized/model/junos.rb3
-rw-r--r--lib/oxidized/model/mlnxos.rb6
-rw-r--r--lib/oxidized/model/nxos.rb8
-rw-r--r--lib/oxidized/model/oneos.rb58
-rw-r--r--lib/oxidized/model/opengear.rb2
-rw-r--r--lib/oxidized/model/pfsense.rb3
-rw-r--r--lib/oxidized/model/powerconnect.rb1
-rw-r--r--lib/oxidized/model/procurve.rb11
-rw-r--r--lib/oxidized/model/routeros.rb4
-rw-r--r--lib/oxidized/model/saos.rb4
-rw-r--r--lib/oxidized/model/siklu.rb19
-rw-r--r--lib/oxidized/model/timos.rb16
-rw-r--r--lib/oxidized/model/tplink.rb65
-rw-r--r--lib/oxidized/model/voltaire.rb56
-rw-r--r--lib/oxidized/node.rb36
-rw-r--r--lib/oxidized/nodes.rb3
-rw-r--r--lib/oxidized/output/gitcrypt.rb244
-rw-r--r--lib/oxidized/source/http.rb31
-rw-r--r--lib/oxidized/worker.rb5
34 files changed, 767 insertions, 60 deletions
diff --git a/lib/oxidized/config.rb b/lib/oxidized/config.rb
index b6b5c40..aba8b63 100644
--- a/lib/oxidized/config.rb
+++ b/lib/oxidized/config.rb
@@ -28,8 +28,9 @@ module Oxidized
asetus.default.retries = 3
asetus.default.prompt = /^([\w.@-]+[#>]\s?)$/
asetus.default.rest = '127.0.0.1:8888' # or false to disable
- asetus.default.vars = {} # could be 'enable'=>'enablePW'
- asetus.default.groups = {} # group level configuration
+ asetus.default.next_adds_job = false # if true, /next adds job, so device is fetched immmeiately
+ asetus.default.vars = {} # could be 'enable'=>'enablePW'
+ asetus.default.groups = {} # group level configuration
asetus.default.pid = File.join(Oxidized::Config::Root, 'pid')
asetus.default.input.default = 'ssh, telnet'
diff --git a/lib/oxidized/hook/slackdiff.rb b/lib/oxidized/hook/slackdiff.rb
new file mode 100644
index 0000000..61f1743
--- /dev/null
+++ b/lib/oxidized/hook/slackdiff.rb
@@ -0,0 +1,34 @@
+require 'slack'
+
+class SlackDiff < Oxidized::Hook
+ def validate_cfg!
+ raise KeyError, 'hook.token is required' unless cfg.has_key?('token')
+ raise KeyError, 'hook.channel is required' unless cfg.has_key?('channel')
+ end
+
+ def run_hook(ctx)
+ if ctx.node
+ if ctx.event.to_s == "post_store"
+ log "Connecting to slack"
+ Slack.configure do |config|
+ config.token = cfg.token
+ config.proxy = cfg.proxy if cfg.has_key?('proxy')
+ end
+ client = Slack::Client.new
+ client.auth_test
+ log "Connected"
+ gitoutput = ctx.node.output.new
+ diff = gitoutput.get_diff ctx.node, ctx.node.group, ctx.commitref, nil
+ title = "#{ctx.node.name.to_s} #{ctx.node.group.to_s} #{ctx.node.model.class.name.to_s.downcase}"
+ log "Posting diff as snippet to #{cfg.channel}"
+ client.files_upload(channels: cfg.channel, as_user: true,
+ content: diff[:patch].lines.to_a[4..-1].join,
+ filetype: "diff",
+ title: title,
+ filename: "change"
+ )
+ log "Finished"
+ end
+ end
+ end
+end
diff --git a/lib/oxidized/input/ssh.rb b/lib/oxidized/input/ssh.rb
index 9a5c508..858d5cd 100644
--- a/lib/oxidized/input/ssh.rb
+++ b/lib/oxidized/input/ssh.rb
@@ -25,7 +25,10 @@ module Oxidized
@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")
+ proxy_command = "ssh "
+ proxy_command += "-o StrictHostKeyChecking=no " unless secure
+ proxy_command += "#{proxy_host} -W %h:%p"
+ proxy = Net::SSH::Proxy::Command.new(proxy_command)
end
ssh_opts = {
:port => port.to_i,
diff --git a/lib/oxidized/model/aireos.rb b/lib/oxidized/model/aireos.rb
index 7056e3f..ba13120 100644
--- a/lib/oxidized/model/aireos.rb
+++ b/lib/oxidized/model/aireos.rb
@@ -44,7 +44,7 @@ class Aireos < Oxidized::Model
out = []
cfg.each_line do |line|
next if line.match /^\s*$/
- next if line.match /rogue (adhoc|client) alert [\da-f]{2}:/
+ next if line.match /rogue (adhoc|client) (alert|Unknown) [\da-f]{2}:/
line = line[1..-1] if line[0] == "\r"
out << line.strip
end
diff --git a/lib/oxidized/model/airos.rb b/lib/oxidized/model/airos.rb
index 775005f..7d82956 100644
--- a/lib/oxidized/model/airos.rb
+++ b/lib/oxidized/model/airos.rb
@@ -1,14 +1,19 @@
class Airos < Oxidized::Model
# Ubiquiti AirOS circa 5.x
-
+
prompt /^[^#]+# /
-
+ comment '# '
+
cmd 'cat /etc/board.info' do |cfg|
cfg.split("\n").map { |line| "# #{line}" }.join("\n") + "\n"
end
-
+
+ cmd 'cat /etc/version' do |cfg|
+ comment "airos version: #{cfg}"
+ end
+
cmd 'sort /tmp/system.cfg'
-
+
cmd :secret do |cfg|
cfg.gsub! /^(users\.\d+\.password|snmp\.community)=.+/, "# \\1=<hidden>"
cfg
diff --git a/lib/oxidized/model/alvarion.rb b/lib/oxidized/model/alvarion.rb
index 3c762de..7a4dcc7 100644
--- a/lib/oxidized/model/alvarion.rb
+++ b/lib/oxidized/model/alvarion.rb
@@ -8,6 +8,8 @@ class Alvarion < Oxidized::Model
end
- cfg :tftp {}
+ cfg :tftp do
+
+ end
end
diff --git a/lib/oxidized/model/aosw.rb b/lib/oxidized/model/aosw.rb
index adf481b..a85ead7 100644
--- a/lib/oxidized/model/aosw.rb
+++ b/lib/oxidized/model/aosw.rb
@@ -1,47 +1,61 @@
class AOSW < Oxidized::Model
- # AOSW Aruba Wireless
+ # AOSW Aruba Wireless, IAP, Instant Controller and Mobility Access Switches
# Used in Alcatel OAW-4750 WLAN controller
# Also Dell controllers
+
+ # HPE Aruba Switches should use a different model as the software is based on the HP Procurve line.
+
+ # Support for IAP & Instant Controller tested with 115, 205, 215 & 325 running 6.4.4.8-4.2.4.5_57965
+ # Support for Mobility Access Switches tested with S2500-48P & S2500-24P running 7.4.1.4_54199 and S2500-24P running 7.4.1.7_57823
+ # All IAPs connected to a Instant Controller will have the same config output. Only the controller needs to be monitored.
comment '# '
- prompt /^\([^)]+\) [#>]/
+ prompt /^\(?.+\)?\s?[#>]/
cmd :all do |cfg|
cfg.each_line.to_a[1..-2].join
end
cmd :secret do |cfg|
+ cfg.gsub!(/secret (\S+)$/, 'secret <secret removed>')
+ cfg.gsub!(/enable secret (\S+)$/, 'enable secret <secret removed>')
cfg.gsub!(/PRE-SHARE (\S+)$/, 'PRE-SHARE <secret removed>')
cfg.gsub!(/ipsec (\S+)$/, 'ipsec <secret removed>')
cfg.gsub!(/community (\S+)$/, 'community <secret removed>')
cfg.gsub!(/ sha (\S+)/, ' sha <secret removed>')
cfg.gsub!(/ des (\S+)/, ' des <secret removed>')
cfg.gsub!(/mobility-manager (\S+) user (\S+) (\S+)/, 'mobility-manager \1 user \2 <secret removed>')
- cfg.gsub!(/mgmt-user (\S+) (\S+) (\S+)$/, 'mgmt-user \1 \2 <secret removed>')
+ cfg.gsub!(/mgmt-user (\S+) (root|guest\-provisioning|network\-operations|read\-only|location\-api\-mgmt) (\S+)$/, 'mgmt-user \1 \2 <secret removed>') #MAS & Wireless Controler
+ cfg.gsub!(/mgmt-user (\S+) (\S+)( (read\-only|guest\-mgmt))?$/, 'mgmt-user \1 <secret removed> \3') #IAP
+#MAS format: mgmt-user <username> <accesslevel> <password hash>
+#IAP format (root user): mgmt-user <username> <password hash>
+#IAP format: mgmt-user <username> <password hash> <access level>
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.gsub!(/user (\S+) (\S+) (\S+)$/, 'user \1 <secret removed> \3')
+ cfg.gsub!(/virtual-controller-key (\S+)$/, 'virtual-controller-key <secret removed>')
cfg
end
cmd 'show version' do |cfg|
- cfg = cfg.each_line.select { |line| not line.match /Switch uptime/i }
+ cfg = cfg.each_line.select { |line| not line.match /(Switch|AP) uptime/i }
rstrip_cfg comment cfg.join
end
cmd 'show inventory' do |cfg|
+ cfg = "" if cfg.match /(Invalid input detected at '\^' marker|Parse error)/ #Don't show for unsupported devices (IAP and MAS)
rstrip_cfg clean cfg
end
cmd 'show slots' do |cfg|
- cfg = "" if cfg.match /Invalid input detected at '\^' marker/ #Don't show for unsupported devices
+ cfg = "" if cfg.match /(Invalid input detected at '\^' marker|Parse error)/ #Don't show for unsupported devices (IAP and MAS)
rstrip_cfg comment cfg
end
cmd 'show license' do |cfg|
- cfg = "" if cfg.match /Invalid input detected at '\^' marker/ #Don't show for unsupported devices
+ cfg = "" if cfg.match /(Invalid input detected at '\^' marker|Parse error)/ #Don't show for unsupported devices (IAP and MAS)
rstrip_cfg comment cfg
end
diff --git a/lib/oxidized/model/asa.rb b/lib/oxidized/model/asa.rb
index df30059..038dd6b 100644
--- a/lib/oxidized/model/asa.rb
+++ b/lib/oxidized/model/asa.rb
@@ -13,9 +13,10 @@ 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! /(ikev[12] ((remote|local)-authentication )?pre-shared-key) (\S+)/, '\1 <secret hidden>'
cfg.gsub! /^(aaa-server TACACS\+? \(\S+\) host.*\n\skey) \S+$/mi, '\1 <secret hidden>'
+ cfg.gsub! /ldap-login-password (\S+)/, 'ldap-login-password <secret hidden>'
+ cfg.gsub! /^snmp-server host (.*) community (\S+)/, 'snmp-server host \1 community <secret hidden>'
cfg
end
diff --git a/lib/oxidized/model/cisconga.rb b/lib/oxidized/model/cisconga.rb
new file mode 100644
index 0000000..73fb51c
--- /dev/null
+++ b/lib/oxidized/model/cisconga.rb
@@ -0,0 +1,19 @@
+class CiscoNGA < Oxidized::Model
+
+ comment '# '
+ prompt /([\w.@-]+[#>]\s?)$/
+
+ cmd 'show version' do |cfg|
+ comment cfg
+ end
+
+ cmd 'show configuration' do |cfg|
+ cfg
+ end
+
+ cfg :ssh do
+ post_login 'terminal length 0'
+ pre_logout 'exit'
+ end
+
+end
diff --git a/lib/oxidized/model/comware.rb b/lib/oxidized/model/comware.rb
index 27b70ae..d926854 100644
--- a/lib/oxidized/model/comware.rb
+++ b/lib/oxidized/model/comware.rb
@@ -18,6 +18,12 @@ class Comware < Oxidized::Model
cfg.each_line.to_a[1..-2].join
end
+ cmd :secret do |cfg|
+ cfg.gsub! /^( snmp-agent community).*/, '\\1 <configuration removed>'
+ cfg.gsub! /^( password hash).*/, '\\1 <configuration removed>'
+ cfg
+ end
+
cfg :telnet do
username /^Username:$/
password /^Password:$/
diff --git a/lib/oxidized/model/cumulus.rb b/lib/oxidized/model/cumulus.rb
index dc6792a..20acb8a 100644
--- a/lib/oxidized/model/cumulus.rb
+++ b/lib/oxidized/model/cumulus.rb
@@ -32,7 +32,10 @@ class Cumulus < Oxidized::Model
cfg += add_comment 'IP Routes'
cfg += cmd 'netstat -rn'
-
+
+ cfg += add_comment 'SNMP settings'
+ cfg += cmd 'cat /etc/snmp/snmpd.conf'
+
cfg += add_comment 'QUAGGA DAEMONS'
cfg += cmd 'cat /etc/quagga/daemons'
@@ -48,21 +51,30 @@ class Cumulus < Oxidized::Model
cfg += add_comment 'QUAGGA OSPF6'
cfg += cmd 'cat /etc/quagga/ospf6d.conf'
+ cfg += add_comment 'QUAGGA CONF'
+ cfg += cmd 'cat /etc/quagga/Quagga.conf'
+
cfg += add_comment 'MOTD'
cfg += cmd 'cat /etc/motd'
cfg += add_comment 'PASSWD'
cfg += cmd 'cat /etc/passwd'
- cfg += add_comment ' SWITCHD'
+ cfg += add_comment 'SWITCHD'
cfg += cmd 'cat /etc/cumulus/switchd.conf'
+ cfg += add_comment 'PORTS'
+ cfg += cmd 'cat /etc/cumulus/ports.conf'
+
+ cfg += add_comment 'TRAFFIC'
+ cfg += cmd 'cat /etc/cumulus/datapath/traffic.conf'
+
cfg += add_comment 'ACL'
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'
diff --git a/lib/oxidized/model/firewareos.rb b/lib/oxidized/model/firewareos.rb
index f2bef4c..f456c60 100644
--- a/lib/oxidized/model/firewareos.rb
+++ b/lib/oxidized/model/firewareos.rb
@@ -1,12 +1,18 @@
class FirewareOS < Oxidized::Model
- prompt /^\[?\w*\]?\w*<?\w*>?#\s*$/
+ prompt /^([\w.@-]+[#>]\s?)$/
comment '-- '
cmd :all do |cfg|
cfg.each_line.to_a[1..-2].join
end
+ # Handle Logon Disclaimer added in XTM 11.9.3
+ expect /^I have read and accept the Logon Disclaimer message. \(yes or no\)\? $/ do |data, re|
+ send "yes\n"
+ data.sub re, ''
+ end
+
cmd 'show sysinfo' do |cfg|
# avoid commits due to uptime
cfg = cfg.each_line.select { |line| not line.match /(.*time.*)|(.*memory.*)|(.*cpu.*)/ }
diff --git a/lib/oxidized/model/fortios.rb b/lib/oxidized/model/fortios.rb
index cdb50d5..cdaa282 100644
--- a/lib/oxidized/model/fortios.rb
+++ b/lib/oxidized/model/fortios.rb
@@ -15,7 +15,8 @@ class FortiOS < Oxidized::Model
end
cmd :secret do |cfg|
- cfg.gsub! /(set (?:passwd|password)).*/, '\\1 <configuration removed>'
+ cfg.gsub! /(set (?:passwd|password|psksecret|secret|key ENC)).*/, '\\1 <configuration removed>'
+ cfg.gsub! /(set private-key).*-+END ENCRYPTED PRIVATE KEY-*"$/m , '\\1 <configuration removed>'
cfg
end
@@ -30,14 +31,18 @@ class FortiOS < Oxidized::Model
cfg << cmd('config global') if @vdom_enabled
cfg << cmd('get hardware status') do |cfg|
- comment cfg
+ comment cfg
end
- cfg << cmd('diagnose autoupdate version') do |cfg|
- comment cfg.each_line.reject { |line| line.match /Last Update|Result/ }.join
+ #default behaviour: include autoupdate output (backwards compatibility)
+ #do not include if variable "show_autoupdate" is set to false
+ if defined?(vars(:fortios_autoupdate)).nil? || vars(:fortios_autoupdate)
+ cfg << cmd('diagnose autoupdate version') do |cfg|
+ comment cfg.each_line.reject { |line| line.match /Last Update|Result/ }.join
+ end
end
- cfg << cmd('end') if @vdom_enabled
+cfg << cmd('end') if @vdom_enabled
cfg << cmd('show')
cfg.join "\n"
@@ -53,3 +58,4 @@ class FortiOS < Oxidized::Model
end
end
+
diff --git a/lib/oxidized/model/ios.rb b/lib/oxidized/model/ios.rb
index c8b0ef3..c3d5543 100644
--- a/lib/oxidized/model/ios.rb
+++ b/lib/oxidized/model/ios.rb
@@ -19,23 +19,96 @@ class IOS < Oxidized::Model
cmd :all do |cfg|
#cfg.gsub! /\cH+\s{8}/, '' # example how to handle pager
#cfg.gsub! /\cH+/, '' # example how to handle pager
+ # get rid of errors for commands that don't work on some devices
+ cfg.gsub! /^% Invalid input detected at '\^' marker\.$|^\s+\^$/, ''
cfg.each_line.to_a[1..-2].join
end
cmd :secret do |cfg|
cfg.gsub! /^(snmp-server community).*/, '\\1 <configuration removed>'
- cfg.gsub! /username (\S+) privilege (\d+) (\S+).*/, '<secret hidden>'
- cfg.gsub! /^username \S+ password \d \S+/, '<secret hidden>'
- cfg.gsub! /^username \S+ secret \d \S+/, '<secret hidden>'
- cfg.gsub! /^enable (password|secret) \d \S+/, '<secret hidden>'
+ cfg.gsub! /^(username \S+ privilege \d+) (\S+).*/, '\\1 <secret hidden>'
+ cfg.gsub! /^(username \S+ password \d) (\S+)/, '\\1 <secret hidden>'
+ cfg.gsub! /^(username \S+ secret \d) (\S+)/, '\\1 <secret hidden>'
+ cfg.gsub! /^(enable (password|secret) \d) (\S+)/, '\\1 <secret hidden>'
cfg.gsub! /^(\s+(?:password|secret)) (?:\d )?\S+/, '\\1 <secret hidden>'
- cfg.gsub! /wpa-psk ascii \d \S+/, '<secret hidden>'
- cfg.gsub! /^tacacs-server key \d \S+/, '<secret hidden>'
+ cfg.gsub! /^(.*wpa-psk ascii \d) (\S+)/, '\\1 <secret hidden>'
+ cfg.gsub! /^(.*key 7) (\d.+)/, '\\1 <secret hidden>'
+ cfg.gsub! /^(tacacs-server key \d) (\S+)/, '\\1 <secret hidden>'
+ cfg.gsub! /^(crypto isakmp key) (\S+) (.*)/, '\\1 <secret hidden> \\3'
cfg
end
cmd 'show version' do |cfg|
- comment cfg.lines.first
+ comments = []
+ comments << cfg.lines.first
+ lines = cfg.lines
+ lines.each_with_index do |line,i|
+ slave = ''
+ slaveslot = ''
+
+ if line.match /^Slave in slot (\d+) is running/
+ slave = " Slave:";
+ slaveslot = ", slot #{$1}";
+ end
+
+ if line.match /^Compiled (.*)$/
+ comments << "Image:#{slave} Compiled: #{$1}"
+ end
+
+ if line.match /^(?:Cisco )?IOS .* Software,? \(([A-Za-z0-9_-]*)\), .*Version\s+(.*)$/
+ comments << "Image:#{slave} Software: #{$1}, #{$2}"
+ end
+
+ if line.match /^ROM: (IOS \S+ )?(System )?Bootstrap.*(Version.*)$/
+ comments << "ROM Bootstrap: #{$3}"
+ end
+
+ if line.match /^BOOTFLASH: .*(Version.*)$/
+ comments << "BOOTFLASH: #{$1}"
+ end
+
+ if line.match /^(\d+[kK]) bytes of (non-volatile|NVRAM)/
+ comments << "Memory: nvram #{$1}"
+ end
+
+ if line.match /^(\d+[kK]) bytes of (flash memory|flash internal|processor board System flash|ATA CompactFlash)/i
+ comments << "Memory: flash #{$1}"
+ end
+
+ if line.match (/^(\d+[kK]) bytes of (Flash|ATA)?.*PCMCIA .*(slot|disk) ?(\d)/i)
+ comments << "Memory: pcmcia #{$2} #{$3}#{$4} #{$1}";
+ end
+
+ if line.match /(\S+(?:\sseries)?)\s+(?:\((\S+)\)\s+processor|\(revision[^)]+\)).*\s+with (\S+k) bytes/i
+ sproc = $1
+ cpu = $2
+ mem = $3
+ cpuxtra = ''
+ comments << "Chassis type:#{slave} #{sproc}";
+ comments << "Memory:#{slave} main #{mem}";
+ # check the next two lines for more CPU info
+ if cfg.lines[i+1].match /processor board id (\S+)/i
+ comments << "Processor ID: #{$1}";
+ end
+ if cfg.lines[i+2].match /(cpu at |processor: |#{cpu} processor,)/i
+ # change implementation to impl and prepend comma
+ cpuxtra = cfg.lines[i+2].gsub(/implementation/,'impl').gsub(/^/,', ').chomp;
+ end
+ comments << "CPU:#{slave} #{cpu}#{cpuxtra}#{slaveslot}";
+ end
+
+ if line.match /^System image file is "([^\"]*)"$/
+ comments << "Image: #{$1}"
+ end
+ end
+ comments << "\n"
+ comment comments.join "\n"
+ end
+
+ cmd 'show vtp status' do |cfg|
+ cfg.gsub! /^$\n/, ''
+ cfg.gsub! /^/, 'VTP: ' if (!cfg.empty?)
+ comment "#{cfg}\n"
end
cmd 'show inventory' do |cfg|
diff --git a/lib/oxidized/model/ironware.rb b/lib/oxidized/model/ironware.rb
index c7c2197..9715c65 100644
--- a/lib/oxidized/model/ironware.rb
+++ b/lib/oxidized/model/ironware.rb
@@ -67,7 +67,7 @@ class IronWare < Oxidized::Model
# match expected prompts on both older and newer
# versions of IronWare
username /^(Please Enter Login Name|Username):/
- password /^(Please Enter )Password:/
+ password /^(Please Enter Password |Password):/
end
#handle pager with enable
diff --git a/lib/oxidized/model/junos.rb b/lib/oxidized/model/junos.rb
index 058e3cf..2f59414 100644
--- a/lib/oxidized/model/junos.rb
+++ b/lib/oxidized/model/junos.rb
@@ -8,6 +8,7 @@ class JunOS < Oxidized::Model
cmd :all do |cfg|
cfg = cfg.lines.to_a[1..-2].join if screenscrape
+ cfg.gsub!(/ scale-subscriber (\s+)(\d+)/,' scale-subscriber <count>')
cfg.lines.map { |line| line.rstrip }.join("\n") + "\n"
end
@@ -36,6 +37,8 @@ class JunOS < Oxidized::Model
end
cmd('show chassis hardware') { |cfg| comment cfg }
+ cmd('show system license') { |cfg| comment cfg }
+ cmd('show system license keys') { |cfg| comment cfg }
cfg :telnet do
username(/^login:/)
diff --git a/lib/oxidized/model/mlnxos.rb b/lib/oxidized/model/mlnxos.rb
index 9542c88..49f3369 100644
--- a/lib/oxidized/model/mlnxos.rb
+++ b/lib/oxidized/model/mlnxos.rb
@@ -13,6 +13,10 @@ class MLNXOS < Oxidized::Model
cfg.gsub! /\[\?1h=\r/, '' # Pager Handling
cfg.gsub! /\r\[K/,'' # Pager Handling
cfg.gsub! /\s/, '' # Linebreak Handling
+ cfg.gsub! /^CPU\ load\ averages\:\s.+/, '' # Omit constantly changing CPU info
+ cfg.gsub! /^System\ memory\:\s.+/, '' # Omit constantly changing memory info
+ cfg.gsub! /^Uptime\:\s.+/, '' # Omit constantly changing uptime info
+ cfg.gsub! /.+Generated\ at\s\d+.+/, '' # Omit constantly changing generation time info
cfg = cfg.lines.to_a[2..-3].join
end
@@ -38,6 +42,6 @@ class MLNXOS < Oxidized::Model
cfg :ssh do
password /^Password:\s*/
- pre_logout 'exit'
+ pre_logout "\nexit"
end
end
diff --git a/lib/oxidized/model/nxos.rb b/lib/oxidized/model/nxos.rb
index fbe772d..e743415 100644
--- a/lib/oxidized/model/nxos.rb
+++ b/lib/oxidized/model/nxos.rb
@@ -3,6 +3,14 @@ class NXOS < Oxidized::Model
prompt /^(\r?[\w.@_()-]+[#]\s?)$/
comment '! '
+ cmd :secret do |cfg|
+ cfg.gsub! /^(snmp-server community).*/, '\\1 <configuration removed>'
+ cfg.gsub! /^(snmp-server user (\S+) (\S+) auth (\S+)) (\S+) (priv) (\S+)/, '\\1 <configuration removed> '
+ cfg.gsub! /^(username \S+ password \d) (\S+)/, '\\1 <secret hidden>'
+ cfg.gsub! /^(radius-server key).*/, '\\1 <secret hidden>'
+ cfg
+ end
+
cmd 'show version' do |cfg|
cfg = cfg.each_line.take_while { |line| not line.match(/uptime/i) }
comment cfg.join ""
diff --git a/lib/oxidized/model/oneos.rb b/lib/oxidized/model/oneos.rb
new file mode 100644
index 0000000..eeaa2ce
--- /dev/null
+++ b/lib/oxidized/model/oneos.rb
@@ -0,0 +1,58 @@
+class OneOS < Oxidized::Model
+
+ prompt /^([\w.@()-]+#\s?)$/
+ comment '! '
+
+ # example how to handle pager
+ #expect /^\s--More--\s+.*$/ do |data, re|
+ # send ' '
+ # data.sub re, ''
+ #end
+
+ # non-preferred way to handle additional PW prompt
+ #expect /^[\w.]+>$/ do |data|
+ # send "enable\n"
+ # send vars(:enable) + "\n"
+ # data
+ #end
+
+ cmd :all do |cfg|
+ #cfg.gsub! /\cH+\s{8}/, '' # example how to handle pager
+ #cfg.gsub! /\cH+/, '' # example how to handle pager
+ cfg.each_line.to_a[1..-2].join
+ end
+
+ cmd :secret do |cfg|
+ cfg.gsub! /^(snmp set-read-community ").*+?(".*)$/, '\\1<secret hidden>\\2'
+ cfg
+ end
+
+ cmd 'show version' do |cfg|
+ comment cfg
+ end
+
+ cmd 'show running-config' do |cfg|
+ cfg = cfg.each_line.to_a[0..-1].join
+ cfg.gsub! /^Building configuration...\s*[^\n]*\n/, ''
+ cfg.gsub! /^Current configuration :\s*[^\n]*\n/, ''
+ cfg
+ end
+
+ cfg :telnet do
+ username /^Username:/
+ password /^Password:/
+ end
+
+ cfg :telnet, :ssh do
+ # preferred way to handle additional passwords
+ if vars :enable
+ post_login do
+ send "enable\n"
+ cmd vars(:enable)
+ end
+ end
+ post_login 'term len 0'
+ pre_logout 'exit'
+ end
+
+end
diff --git a/lib/oxidized/model/opengear.rb b/lib/oxidized/model/opengear.rb
index 7f801f8..b7c697f 100644
--- a/lib/oxidized/model/opengear.rb
+++ b/lib/oxidized/model/opengear.rb
@@ -1,6 +1,8 @@
class OpenGear < Oxidized::Model
comment '# '
+
+ prompt /^(\$\s)?$/
cmd :secret do |cfg|
cfg.gsub!(/password (\S+)/, 'password <secret removed>')
diff --git a/lib/oxidized/model/pfsense.rb b/lib/oxidized/model/pfsense.rb
index c02c0d0..782969e 100644
--- a/lib/oxidized/model/pfsense.rb
+++ b/lib/oxidized/model/pfsense.rb
@@ -7,7 +7,8 @@ class PfSense < Oxidized::Model
end
cmd 'cat /cf/conf/config.xml' do |cfg|
- cfg.gsub! /\s<revision>\s*.*\s*<time>\d*<\/time>\s*.*\s*<\/revision>/, ''
+ cfg.gsub! /\s<revision>\s*<time>\d*<\/time>\s*.*\s*.*\s*<\/revision>/, ''
+ cfg.gsub! /\s<last_rule_upd_time>\d*<\/last_rule_upd_time>/, ''
cfg
end
diff --git a/lib/oxidized/model/powerconnect.rb b/lib/oxidized/model/powerconnect.rb
index ac36c26..618f05a 100644
--- a/lib/oxidized/model/powerconnect.rb
+++ b/lib/oxidized/model/powerconnect.rb
@@ -67,6 +67,7 @@ class PowerConnect < Oxidized::Model
end
out << line.strip
end
+ out = out.select { |line| not line[/Up\sTime/] }
out = comment out.join "\n"
out << "\n"
end
diff --git a/lib/oxidized/model/procurve.rb b/lib/oxidized/model/procurve.rb
index c117df3..7dcf1fd 100644
--- a/lib/oxidized/model/procurve.rb
+++ b/lib/oxidized/model/procurve.rb
@@ -1,11 +1,16 @@
class Procurve < Oxidized::Model
- # some models start lines with \r
+ # some models start lines with \r
# previous command is repeated followed by "\eE", which sometimes ends up on last line
- prompt /^\r?([\w -]+\eE)?([\w.-]+# )$/
+ prompt /^\r?([\w.-]+# )$/
comment '! '
+ # replace next line control sequence with a new line
+ expect /(\e\[1M\e\[\??\d+(;\d+)*[A-Za-z]\e\[1L)|(\eE)/ do |data, re|
+ data.gsub re, "\n"
+ end
+
# replace all used vt100 control sequences
expect /\e\[\??\d+(;\d+)*[A-Za-z]/ do |data, re|
data.gsub re, ''
@@ -17,7 +22,7 @@ class Procurve < Oxidized::Model
end
cmd :all do |cfg|
- cfg = cfg.each_line.to_a[1..-3].join
+ cfg = cfg.each_line.to_a[1..-2].join
cfg = cfg.gsub /^\r/, ''
end
diff --git a/lib/oxidized/model/routeros.rb b/lib/oxidized/model/routeros.rb
index a92ad5e..5717100 100644
--- a/lib/oxidized/model/routeros.rb
+++ b/lib/oxidized/model/routeros.rb
@@ -6,6 +6,10 @@ class RouterOS < Oxidized::Model
comment cfg
end
+ cmd '/system package update print' do |cfg|
+ comment cfg
+ end
+
cmd '/export' do |cfg|
cfg.gsub! /\x1B\[([0-9]{1,3}((;[0-9]{1,3})*)?)?[m|K]/, '' # strip ANSI colours
cfg.gsub! /\\\r\n\s+/, '' # strip new line
diff --git a/lib/oxidized/model/saos.rb b/lib/oxidized/model/saos.rb
index 5d460cf..5a4e79e 100644
--- a/lib/oxidized/model/saos.rb
+++ b/lib/oxidized/model/saos.rb
@@ -2,7 +2,7 @@ class SAOS < Oxidized::Model
# Ciena SAOS switch
# used for 6.x devices
-
+
comment '! '
cmd :all do |cfg|
@@ -10,6 +10,8 @@ class SAOS < Oxidized::Model
end
cmd 'configuration show' do |cfg|
+ cfg.gsub! /^! Created: [^\n]*\n/, ''
+ cfg.gsub! /^! On terminal: [^\n]*\n/, ''
cfg
end
diff --git a/lib/oxidized/model/siklu.rb b/lib/oxidized/model/siklu.rb
new file mode 100644
index 0000000..2bdfbc3
--- /dev/null
+++ b/lib/oxidized/model/siklu.rb
@@ -0,0 +1,19 @@
+class Siklu < Oxidized::Model
+
+ # Siklu EtherHaul #
+
+ prompt /^[\w-]+>$/
+
+ cmd 'copy startup-configuration display' do |cfg|
+ cfg.each_line.to_a[2..2].join
+ end
+
+ cmd 'copy running-configuration display' do |cfg|
+ cfg.each_line.to_a[3..-2].join
+ end
+
+ cfg :ssh do
+ pre_logout 'exit'
+ end
+
+end
diff --git a/lib/oxidized/model/timos.rb b/lib/oxidized/model/timos.rb
index d40e845..c230a8f 100644
--- a/lib/oxidized/model/timos.rb
+++ b/lib/oxidized/model/timos.rb
@@ -18,6 +18,8 @@ class TiMOS < Oxidized::Model
# Show the boot options file.
#
cmd 'show bof' do |cfg|
+ cfg.gsub! /# Finished .*/, ''
+ cfg.gsub! /# Generated .*/, ''
comment cfg
end
@@ -29,6 +31,8 @@ class TiMOS < Oxidized::Model
# Strip uptime.
#
cfg.sub! /^System Up Time.*\n/, ''
+ cfg.gsub! /# Finished .*/, ''
+ cfg.gsub! /# Generated .*/, ''
comment cfg
end
@@ -36,6 +40,8 @@ class TiMOS < Oxidized::Model
# Show the card state.
#
cmd 'show card state' do |cfg|
+ cfg.gsub! /# Finished .*/, ''
+ cfg.gsub! /# Generated .*/, ''
comment cfg
end
@@ -48,6 +54,8 @@ class TiMOS < Oxidized::Model
#
cfg.gsub! /\r/, ''
cfg.gsub! /[\b][\b][\b]/, "\n"
+ cfg.gsub! /# Finished .*/, ''
+ cfg.gsub! /# Generated .*/, ''
comment cfg
end
@@ -55,6 +63,8 @@ class TiMOS < Oxidized::Model
# Show the running debug configuration.
#
cmd 'show debug' do |cfg|
+ cfg.gsub! /# Finished .*/, ''
+ cfg.gsub! /# Generated .*/, ''
comment cfg
end
@@ -66,6 +76,8 @@ class TiMOS < Oxidized::Model
# Strip carriage returns.
#
cfg.gsub! /\r/, ''
+ cfg.gsub! /# Finished .*/, ''
+ cfg.gsub! /# Generated .*/, ''
comment cfg
end
@@ -77,6 +89,8 @@ class TiMOS < Oxidized::Model
# Strip carriage returns.
#
cfg.gsub! /\r/, ''
+ cfg.gsub! /# Finished .*/, ''
+ cfg.gsub! /# Generated .*/, ''
comment cfg
end
@@ -88,6 +102,8 @@ class TiMOS < Oxidized::Model
# Strip carriage returns.
#
cfg.gsub! /\r/, ''
+ cfg.gsub! /# Finished .*/, ''
+ cfg.gsub! /# Generated .*/, ''
end
cfg :telnet do
diff --git a/lib/oxidized/model/tplink.rb b/lib/oxidized/model/tplink.rb
new file mode 100644
index 0000000..bf13803
--- /dev/null
+++ b/lib/oxidized/model/tplink.rb
@@ -0,0 +1,65 @@
+class TPLink < Oxidized::Model
+
+ # tp-link prompt
+ prompt /^\r?([\w.@()-]+[#>]\s?)$/
+ comment '! '
+
+ # handle paging
+ # workaround for sometimes missing whitespaces with "\s?"
+ expect /Press\s?any\s?key\s?to\s?continue\s?\(Q\s?to\s?quit\)/ do |data, re|
+ send ' '
+ data.sub re, ''
+ end
+
+ # send carriage return because \n with the command is not enough
+ # checks if line ends with prompt >,# or \r,\nm otherwise send \r
+ expect /[^>#\r\n]$/ do |data, re|
+ send "\r"
+ data.sub re, ''
+ end
+
+ cmd :all do |cfg|
+ # normalize linefeeds
+ cfg.gsub! /(\r|\r\n|\n\r)/,"\n"
+ # remove empty lines
+ cfg.each_line.reject { |line| line.match /^[\r\n\s\u0000#]+$/ }.join
+ end
+
+ cmd :secret do |cfg|
+ cfg.gsub! /^(snmp-server community).*/, '\\1 <configuration removed>'
+ cfg.gsub! /secret (\d+) (\S+).*/, '<secret hidden>'
+ cfg
+ end
+
+ cmd 'show system-info' do |cfg|
+ comment cfg.each_line.to_a[3..-3].join
+ end
+
+ cmd 'show running-config' do |cfg|
+ lines = cfg.each_line.to_a[1..-1]
+ # cut config after "end"
+ lines[0..lines.index("end\n")].join
+ end
+
+ cfg :telnet, :ssh do
+ username /^User ?[nN]ame:/
+ password /^\r?Password:/
+ end
+
+ cfg :telnet, :ssh do
+ if vars :enable
+ post_login do
+ send "enable\r"
+ cmd vars(:enable)
+ end
+ end
+
+ pre_logout do
+ send "exit\r"
+ send "logout\r"
+ end
+
+ end
+
+end
+
diff --git a/lib/oxidized/model/voltaire.rb b/lib/oxidized/model/voltaire.rb
new file mode 100644
index 0000000..1e7fad2
--- /dev/null
+++ b/lib/oxidized/model/voltaire.rb
@@ -0,0 +1,56 @@
+class VOLTAIRE < Oxidized::Model
+
+ prompt /([\w.@()-\[:\s\]]+[#>]\s|(One or more tests have failed.*))$/
+ comment '## '
+
+ # Pager Handling
+ expect /.+lines\s\d+\-\d+([\s]|\/\d+\s\(END\)\s).+$/ do |data, re|
+ send ' '
+ data.sub re, ''
+ end
+
+
+ cmd :all do |cfg|
+ cfg.gsub! /\[\?1h=\r/, '' # Pager Handling
+ cfg.gsub! /\r\[K/,'' # Pager Handling
+ cfg.gsub! /\s/, '' # Linebreak Handling
+ cfg.gsub! /^CPU\ load\ averages\:\s.+/, '' # Omit constantly changing CPU info
+ cfg.gsub! /^System\ memory\:\s.+/, '' # Omit constantly changing memory info
+ cfg.gsub! /^Uptime\:\s.+/, '' # Omit constantly changing uptime info
+ cfg.gsub! /.+Generated\ at\s\d+.+/, '' # Omit constantly changing generation time info
+ cfg = cfg.lines.to_a[2..-3].join
+ end
+
+ cmd :secret do |cfg|
+ cfg.gsub! /(snmp-server community).*/, ' <snmp-server community configuration removed>'
+ cfg.gsub! /username (\S+) password (\d+) (\S+).*/, '<secret hidden>'
+ cfg
+ end
+
+
+ cmd 'version show' do |cfg|
+ comment cfg
+ end
+
+ cmd 'firmware-version show' do |cfg|
+ comment cfg
+ end
+
+ cmd 'remote show' do |cfg|
+ cfg
+ end
+
+ cmd 'sm-info show' do |cfg|
+ cfg
+ end
+
+ cmd ' show' do |cfg|
+ cfg
+ end
+
+ cfg :ssh do
+ post_login "no\n"
+ password /^Password:\s*/
+ pre_logout 'exit'
+ end
+end
diff --git a/lib/oxidized/node.rb b/lib/oxidized/node.rb
index 6f89b56..cf71e48 100644
--- a/lib/oxidized/node.rb
+++ b/lib/oxidized/node.rb
@@ -166,18 +166,32 @@ module Oxidized
end
def resolve_repo opt
- return unless is_git? opt
-
- remote_repo = Oxidized.config.output.git.repo
-
- if remote_repo.is_a?(::String)
- if Oxidized.config.output.git.single_repo? || @group.nil?
- remote_repo
+ if is_git? opt
+ remote_repo = Oxidized.config.output.git.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
+ elsif is_gitcrypt? opt
+ remote_repo = Oxidized.config.output.gitcrypt.repo
+
+ if remote_repo.is_a?(::String)
+ if Oxidized.config.output.gitcrypt.single_repo? || @group.nil?
+ remote_repo
+ else
+ File.join(File.dirname(remote_repo), @group + '.git')
+ end
else
- File.join(File.dirname(remote_repo), @group + '.git')
+ remote_repo[@group]
end
else
- remote_repo[@group]
+ return
end
end
@@ -212,5 +226,9 @@ module Oxidized
(opt[:output] || Oxidized.config.output.default) == 'git'
end
+ def is_gitcrypt? opt
+ (opt[:output] || Oxidized.config.output.default) == 'gitcrypt'
+ end
+
end
end
diff --git a/lib/oxidized/nodes.rb b/lib/oxidized/nodes.rb
index f5a1ad0..6751c7a 100644
--- a/lib/oxidized/nodes.rb
+++ b/lib/oxidized/nodes.rb
@@ -4,7 +4,7 @@ module Oxidized
class Oxidized::NotSupported < OxidizedError; end
class Oxidized::NodeNotFound < OxidizedError; end
class Nodes < Array
- attr_accessor :source
+ attr_accessor :source, :jobs
alias :put :unshift
def load node_want=nil
with_lock do
@@ -73,6 +73,7 @@ module Oxidized
# set last job to nil so that the node is picked for immediate update
n.last = nil
put n
+ jobs.want += 1 if Oxidized.config.next_adds_job?
end
end
end
diff --git a/lib/oxidized/output/gitcrypt.rb b/lib/oxidized/output/gitcrypt.rb
new file mode 100644
index 0000000..b0d80f2
--- /dev/null
+++ b/lib/oxidized/output/gitcrypt.rb
@@ -0,0 +1,244 @@
+module Oxidized
+ class GitCrypt < Output
+ class GitCryptError < OxidizedError; end
+ begin
+ require 'git'
+ rescue LoadError
+ raise OxidizedError, 'git not found: sudo gem install ruby-git'
+ end
+
+ attr_reader :commitref
+
+ def initialize
+ @cfg = Oxidized.config.output.gitcrypt
+ @gitcrypt_cmd = "/usr/bin/git-crypt"
+ @gitcrypt_init = @gitcrypt_cmd + " init"
+ @gitcrypt_unlock = @gitcrypt_cmd + " unlock"
+ @gitcrypt_lock = @gitcrypt_cmd + " lock"
+ @gitcrypt_adduser = @gitcrypt_cmd + " add-gpg-user --trusted "
+ end
+
+ def setup
+ if @cfg.empty?
+ Oxidized.asetus.user.output.gitcrypt.user = 'Oxidized'
+ Oxidized.asetus.user.output.gitcrypt.email = 'o@example.com'
+ Oxidized.asetus.user.output.gitcrypt.repo = File.join(Config::Root, 'oxidized.git')
+ Oxidized.asetus.save :user
+ raise NoConfig, 'no output git config, edit ~/.config/oxidized/config'
+ end
+
+ if @cfg.repo.respond_to?(:each)
+ @cfg.repo.each do |group, repo|
+ @cfg.repo["#{group}="] = File.expand_path repo
+ end
+ else
+ @cfg.repo = File.expand_path @cfg.repo
+ end
+ end
+
+ def crypt_init repo
+ repo.chdir do
+ system(@gitcrypt_init)
+ @cfg.users.each do |user|
+ system("#{@gitcrypt_adduser} #{user}")
+ end
+ File.write(".gitattributes", "* filter=git-crypt diff=git-crypt\n.gitattributes !filter !diff")
+ repo.add(".gitattributes")
+ repo.commit("Initial commit: crypt all config files")
+ end
+ end
+
+ def lock repo
+ repo.chdir do
+ system(@gitcrypt_lock)
+ end
+ end
+
+ def unlock repo
+ repo.chdir do
+ system(@gitcrypt_unlock)
+ end
+ end
+
+ def store file, outputs, opt={}
+ @msg = opt[:msg]
+ @user = (opt[:user] or @cfg.user)
+ @email = (opt[:email] or @cfg.email)
+ @opt = opt
+ @commitref = nil
+ repo = @cfg.repo
+
+ outputs.types.each do |type|
+ type_cfg = ''
+ 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
+ if @cfg.type_as_directory?
+ type_file = type + '/' + type_file
+ type_repo = repo
+ end
+ update type_repo, type_file, output
+ end
+ update type_repo, file, type_cfg
+ end
+
+ update repo, file, outputs.to_cfg
+ end
+
+
+ def fetch node, group
+ begin
+ repo, path = yield_repo_and_path(node, group)
+ repo = Git.open repo
+ unlock repo
+ index = repo.index
+ # Empty repo ?
+ empty = File.exists? index.path
+ if empty
+ raise 'Empty git repo'
+ else
+ File.read path
+ end
+ lock repo
+ rescue
+ 'node not found'
+ end
+ end
+
+ # give a hash of all oid revision for the given node, and the date of the commit
+ def version node, group
+ begin
+ repo, path = yield_repo_and_path(node, group)
+
+ repo = Git.open repo
+ unlock repo
+ walker = repo.log.path(path)
+ i = -1
+ tab = []
+ walker.each do |commit|
+ hash = {}
+ hash[:date] = commit.date.to_s
+ hash[:oid] = commit.objectish
+ hash[:author] = commit.author
+ hash[:message] = commit.message
+ tab[i += 1] = hash
+ end
+ walker.reset
+ tab
+ rescue
+ 'node not found'
+ end
+ end
+
+ #give the blob of a specific revision
+ def get_version node, group, oid
+ begin
+ repo, path = yield_repo_and_path(node, group)
+ repo = Git.open repo
+ unlock repo
+ repo.gtree(oid).files[path].contents
+ rescue
+ 'version not found'
+ ensure
+ lock repo
+ end
+ end
+
+ #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
+ diff_commits = nil
+ repo, path = yield_repo_and_path(node, group)
+ repo = Git.open repo
+ unlock repo
+ commit = repo.gcommit(oid1)
+
+ if oid2
+ commit_old = repo.gcommit(oid2)
+ diff = repo.diff(commit_old, commit)
+ stats = [diff.stats[:files][node.name][:insertions], diff.stats[:files][node.name][:deletions]]
+ diff.each do |patch|
+ if /#{node.name}\s+/.match(patch.patch.to_s.lines.first)
+ diff_commits = {:patch => patch.patch.to_s, :stat => stats}
+ break
+ end
+ end
+ else
+ stat = commit.parents[0].diff(commit).stats
+ stat = [stat[:files][node.name][:insertions],stat[:files][node.name][:deletions]]
+ patch = commit.parents[0].diff(commit).patch
+ diff_commits = {:patch => patch, :stat => stat}
+ end
+ lock repo
+ diff_commits
+ rescue
+ 'no diffs'
+ ensure
+ lock repo
+ end
+ end
+
+ 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?
+
+ if @opt[:group]
+ if @cfg.single_repo?
+ file = File.join @opt[:group], file
+ else
+ repo = if repo.is_a?(::String)
+ File.join File.dirname(repo), @opt[:group] + '.git'
+ else
+ repo[@opt[:group]]
+ end
+ end
+ end
+
+ begin
+ update_repo repo, file, data, @msg, @user, @email
+ rescue Git::GitExecuteError, ArgumentError => open_error
+ Oxidized.logger.debug "open_error #{open_error} #{file}"
+ begin
+ grepo = Git.init repo
+ crypt_init grepo
+ rescue => create_error
+ raise GitCryptError, "first '#{open_error.message}' was raised while opening git repo, then '#{create_error.message}' was while trying to create git repo"
+ end
+ retry
+ end
+ end
+
+ def update_repo repo, file, data, msg, user, email
+ grepo = Git.open repo
+ grepo.config('user.name', user)
+ grepo.config('user.email', email)
+ grepo.chdir do
+ unlock grepo
+ File.write(file, data)
+ grepo.add(file)
+ if grepo.status[file].nil?
+ grepo.commit(msg)
+ @commitref = grepo.log(1).first.objectish
+ true
+ elsif !grepo.status[file].type.nil?
+ grepo.commit(msg)
+ @commitref = grepo.log(1).first.objectish
+ true
+ end
+ lock grepo
+ end
+ end
+ end
+end
diff --git a/lib/oxidized/source/http.rb b/lib/oxidized/source/http.rb
index 4fd388b..6c12f29 100644
--- a/lib/oxidized/source/http.rb
+++ b/lib/oxidized/source/http.rb
@@ -29,25 +29,27 @@ class HTTP < Source
end
request = Net::HTTP::Get.new(uri.request_uri, headers)
- if (@cfg.user && @cfg.pass)
+ if (@cfg.user? && @cfg.pass?)
request.basic_auth(@cfg.user,@cfg.pass)
end
response = http.request(request)
data = JSON.parse(response.body)
- data.each do |line|
- next if line.empty?
+ data.each do |node|
+ next if node.empty?
# map node parameters
keys = {}
- @cfg.map.each do |key, position|
- keys[key.to_sym] = node_var_interpolate line[position]
+ @cfg.map.each do |key, want_position|
+ want_positions = want_position.split('.')
+ keys[key.to_sym] = node_var_interpolate node.dig(*want_positions)
end
keys[:model] = map_model keys[:model] if keys.key? :model
# map node specific vars
vars = {}
- @cfg.vars_map.each do |key, position|
- vars[key.to_sym] = node_var_interpolate line[position]
+ @cfg.vars_map.each do |key, want_position|
+ want_positions = want_position.split('.')
+ vars[key.to_sym] = node_var_interpolate node.dig(*want_positions)
end
keys[:vars] = vars unless vars.empty?
@@ -58,3 +60,18 @@ class HTTP < Source
end
end
+
+if RUBY_VERSION < '2.3'
+ class Hash
+ def dig(key, *rest)
+ value = self[key]
+ if value.nil? || rest.empty?
+ value
+ elsif value.respond_to?(:dig)
+ value.dig(*rest)
+ else # foo.bar.baz (bar exist but is not hash)
+ return nil
+ end
+ end
+ end
+end
diff --git a/lib/oxidized/worker.rb b/lib/oxidized/worker.rb
index 1952d01..80d65cb 100644
--- a/lib/oxidized/worker.rb
+++ b/lib/oxidized/worker.rb
@@ -3,8 +3,9 @@ module Oxidized
require 'oxidized/jobs'
class Worker
def initialize nodes
- @nodes = nodes
- @jobs = Jobs.new(Oxidized.config.threads, Oxidized.config.interval, @nodes)
+ @nodes = nodes
+ @jobs = Jobs.new(Oxidized.config.threads, Oxidized.config.interval, @nodes)
+ @nodes.jobs = @jobs
Thread.abort_on_exception = true
end