oxidized 0.30.1 → 0.32.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +3 -4
  3. data/.github/workflows/stale.yml +4 -2
  4. data/.rubocop.yml +18 -3
  5. data/.rubocop_todo.yml +4 -11
  6. data/CHANGELOG.md +93 -1
  7. data/CONTRIBUTING.md +5 -0
  8. data/Dockerfile +84 -20
  9. data/README.md +5 -21
  10. data/Rakefile +31 -2
  11. data/docs/Configuration.md +50 -14
  12. data/docs/Creating-Models.md +75 -4
  13. data/docs/DeviceSimulation.md +184 -0
  14. data/docs/Hooks.md +39 -5
  15. data/docs/Issues.md +97 -0
  16. data/docs/Model-Notes/APC_AOS.md +29 -16
  17. data/docs/Model-Notes/Cumulus.md +5 -0
  18. data/docs/Model-Notes/FSOS.md +6 -0
  19. data/docs/Model-Notes/FortiOS.md +21 -5
  20. data/docs/Model-Notes/HPEAruba.md +31 -0
  21. data/docs/Model-Notes/OS6.md +10 -0
  22. data/docs/Model-Notes/RouterOS.md +15 -0
  23. data/docs/Model-Notes/SikluMHTG.md +7 -0
  24. data/docs/ModelUnitTests.md +186 -0
  25. data/docs/Outputs.md +2 -0
  26. data/docs/Release.md +18 -15
  27. data/docs/Sources.md +21 -0
  28. data/docs/Supported-OS-Types.md +14 -7
  29. data/docs/Troubleshooting.md +35 -0
  30. data/examples/podman-compose/Makefile +59 -17
  31. data/examples/podman-compose/README.md +63 -27
  32. data/examples/podman-compose/docker-compose.yml +11 -2
  33. data/examples/podman-compose/gitserver/.gitignore +1 -0
  34. data/examples/podman-compose/gitserver/Dockerfile +14 -0
  35. data/examples/podman-compose/model-simulation/Dockerfile-model +1 -1
  36. data/examples/podman-compose/model-simulation/asternos.sh +2 -0
  37. data/examples/podman-compose/oxidized-config/.gitignore +2 -0
  38. data/examples/podman-compose/oxidized-config/config +1 -1
  39. data/examples/podman-compose/oxidized-config/config_csv-file +46 -0
  40. data/examples/podman-compose/oxidized-config/config_csv-gitserver +56 -0
  41. data/examples/podman-compose/oxidized-ssh/.gitignore +1 -0
  42. data/extra/device2yaml.rb +245 -0
  43. data/extra/gitdiff-msteams.sh +32 -5
  44. data/extra/nagios_check_failing_nodes.rb +1 -1
  45. data/extra/rest_client.rb +1 -1
  46. data/lib/oxidized/config.rb +8 -2
  47. data/lib/oxidized/hook/githubrepo.rb +37 -7
  48. data/lib/oxidized/hook/slackdiff.rb +29 -7
  49. data/lib/oxidized/input/http.rb +1 -0
  50. data/lib/oxidized/input/ssh.rb +13 -5
  51. data/lib/oxidized/input/telnet.rb +1 -1
  52. data/lib/oxidized/manager.rb +17 -16
  53. data/lib/oxidized/model/aos7.rb +2 -0
  54. data/lib/oxidized/model/aoscx.rb +16 -2
  55. data/lib/oxidized/model/aosw.rb +8 -2
  56. data/lib/oxidized/model/apc_aos.rb +1 -1
  57. data/lib/oxidized/model/arubainstant.rb +90 -0
  58. data/lib/oxidized/model/asa.rb +2 -1
  59. data/lib/oxidized/model/asyncos.rb +1 -1
  60. data/lib/oxidized/model/audiocodes.rb +2 -2
  61. data/lib/oxidized/model/cnos.rb +13 -10
  62. data/lib/oxidized/model/cumulus.rb +19 -2
  63. data/lib/oxidized/model/dlink.rb +1 -0
  64. data/lib/oxidized/model/dlinknextgen.rb +3 -0
  65. data/lib/oxidized/model/edgecos.rb +2 -1
  66. data/lib/oxidized/model/enterprise_sonic.rb +46 -0
  67. data/lib/oxidized/model/eos.rb +2 -0
  68. data/lib/oxidized/model/f5os.rb +17 -0
  69. data/lib/oxidized/model/firewareos.rb +10 -1
  70. data/lib/oxidized/model/fortios.rb +24 -1
  71. data/lib/oxidized/model/fsos.rb +5 -1
  72. data/lib/oxidized/model/garderos.rb +43 -0
  73. data/lib/oxidized/model/h3c.rb +1 -1
  74. data/lib/oxidized/model/ibos.rb +1 -0
  75. data/lib/oxidized/model/ios.rb +20 -12
  76. data/lib/oxidized/model/iosxr.rb +1 -1
  77. data/lib/oxidized/model/junos.rb +1 -1
  78. data/lib/oxidized/model/kornfeldos.rb +33 -0
  79. data/lib/oxidized/model/lenovonos.rb +2 -0
  80. data/lib/oxidized/model/linuxgeneric.rb +1 -1
  81. data/lib/oxidized/model/model.rb +2 -2
  82. data/lib/oxidized/model/netgear.rb +1 -1
  83. data/lib/oxidized/model/nodegrid.rb +1 -1
  84. data/lib/oxidized/model/nsxdfw.rb +30 -0
  85. data/lib/oxidized/model/nxos.rb +2 -1
  86. data/lib/oxidized/model/os6.rb +48 -0
  87. data/lib/oxidized/model/rgos.rb +1 -1
  88. data/lib/oxidized/model/riverbed.rb +104 -0
  89. data/lib/oxidized/model/routeros.rb +2 -2
  90. data/lib/oxidized/model/saos.rb +18 -1
  91. data/lib/oxidized/model/siklumhtg.rb +22 -0
  92. data/lib/oxidized/model/sonicos.rb +8 -2
  93. data/lib/oxidized/model/tplink.rb +1 -0
  94. data/lib/oxidized/model/uplinkolt.rb +46 -0
  95. data/lib/oxidized/model/vyatta.rb +2 -2
  96. data/lib/oxidized/model/xos.rb +7 -0
  97. data/lib/oxidized/node.rb +30 -18
  98. data/lib/oxidized/nodes.rb +13 -5
  99. data/lib/oxidized/output/file.rb +45 -42
  100. data/lib/oxidized/output/git.rb +185 -160
  101. data/lib/oxidized/output/gitcrypt.rb +188 -186
  102. data/lib/oxidized/output/http.rb +53 -51
  103. data/lib/oxidized/output/output.rb +6 -4
  104. data/lib/oxidized/source/csv.rb +44 -49
  105. data/lib/oxidized/source/http.rb +63 -81
  106. data/lib/oxidized/source/jsonfile.rb +63 -0
  107. data/lib/oxidized/source/source.rb +73 -18
  108. data/lib/oxidized/source/sql.rb +66 -59
  109. data/lib/oxidized/version.rb +2 -2
  110. data/oxidized.gemspec +25 -18
  111. metadata +115 -21
@@ -0,0 +1,104 @@
1
+ class Riverbed < Oxidized::Model
2
+ using Refinements
3
+
4
+ # Define the prompt
5
+ prompt /^.* *[\w-]+ *[#>] *$/
6
+
7
+ # Define comment character
8
+ comment '! '
9
+
10
+ # Remove sensitive information
11
+ cmd :secret do |cfg|
12
+ cfg.gsub! /^( *tacacs-server (.+ )?key) .+/, '\\1 <secret hidden>'
13
+ cfg.gsub! /^( *username .+ (password|secret) \d) .+/, '\\1 <secret hidden>'
14
+ cfg.gsub! /^( *ntp server .+ key) .+/, '\\1 <secret hidden>'
15
+ cfg.gsub! /^( *ntp peer .+ key) .+/, '\\1 <secret hidden>'
16
+ cfg.gsub! /^( *snmp-server community).*/, '\\1 <configuration removed>'
17
+ cfg.gsub! /^( *ip security shared secret).*/, '\\1 <secret hidden>'
18
+ cfg.gsub! /^( *service shared-secret secret client).*/, '\\1 <secret hidden>'
19
+ cfg.gsub! /^( *service shared-secret secret server).*/, '\\1 <secret hidden>'
20
+ cfg
21
+ end
22
+
23
+ # Get version information and output it as comments
24
+ cmd 'show version' do |cfg|
25
+ cfg = cfg.cut_both
26
+
27
+ output = ''
28
+ cfg.each_line do |line|
29
+ line.strip!
30
+ output << comment("Product name: #{Regexp.last_match(1)}\n") if line =~ /^Product name:\s+(.*)$/
31
+ output << comment("Product release: #{Regexp.last_match(1)}\n") if line =~ /^Product release:\s+(.*)$/
32
+ output << comment("Build ID: #{Regexp.last_match(1)}\n") if line =~ /^Build ID:\s+(.*)$/
33
+ output << comment("Build date: #{Regexp.last_match(1)}\n") if line =~ /^Build date:\s+(.*)$/
34
+ output << comment("Build arch: #{Regexp.last_match(1)}\n") if line =~ /^Build arch:\s+(.*)$/
35
+ output << comment("Built by: #{Regexp.last_match(1)}\n") if line =~ /^Built by:\s+(.*)$/
36
+ output << comment("Product model: #{Regexp.last_match(1)}\n") if line =~ /^Product model:\s+(.*)$/
37
+ output << comment("Number of CPUs: #{Regexp.last_match(1)}\n") if line =~ /^Number of CPUs:\s+(.*)$/
38
+ end
39
+ output + "\n"
40
+ end
41
+
42
+ # Get hardware information and output it as comments
43
+ cmd 'show hardware all' do |cfg|
44
+ cfg = cfg.cut_both
45
+
46
+ output = ''
47
+ cfg.each_line do |line|
48
+ line.strip!
49
+ output << comment("Hardware revision: #{Regexp.last_match(1)}\n") if line =~ /^Hardware revision:\s+(.*)$/
50
+ output << comment("Mainboard: #{Regexp.last_match(1)}\n") if line =~ /^Mainboard:\s+(.*)$/
51
+ if line =~ /^Slot (\d+):\s+\.*\s+(.*)$/
52
+ slot_number = Regexp.last_match(1)
53
+ slot_info = Regexp.last_match(2)
54
+ output << comment("Slot #{slot_number}: #{slot_info}\n")
55
+ end
56
+ output << comment("System led: #{Regexp.last_match(1)}\n") if line =~ /^System led:\s+(.*)$/
57
+ end
58
+ output + "\n"
59
+ end
60
+
61
+ # Get serial information and output it as comment
62
+ cmd 'show info' do |cfg|
63
+ cfg = cfg.cut_both
64
+
65
+ output = ''
66
+ cfg.each_line do |line|
67
+ line.strip!
68
+ output << comment("Serial: #{Regexp.last_match(1)}\n") if line =~ /^Serial:\s+(.*)$/
69
+ end
70
+ output + "\n"
71
+ end
72
+
73
+ # Get the running configuration
74
+ cmd 'show running-config' do |cfg|
75
+ cfg = cfg.cut_both
76
+
77
+ cfg = cfg.each_line.map do |line|
78
+ if line =~ /^(.*##.*?##)(.*)$/
79
+ comment_part = Regexp.last_match(1).strip
80
+ command_part = Regexp.last_match(2).strip
81
+ comment_line = comment(comment_part)
82
+ if command_part.empty?
83
+ comment_line + "\n"
84
+ else
85
+ comment_line + "\n" + command_part + "\n"
86
+ end
87
+ else
88
+ line
89
+ end
90
+ end.join
91
+
92
+ cfg
93
+ end
94
+
95
+ # SSH configuration
96
+ cfg :ssh do
97
+ post_login do
98
+ cmd 'enable'
99
+ cmd 'terminal length 0'
100
+ cmd 'terminal width 1024'
101
+ end
102
+ pre_logout 'exit'
103
+ end
104
+ end
@@ -14,8 +14,8 @@ class RouterOS < Oxidized::Model
14
14
  cfg
15
15
  end
16
16
 
17
- cmd '/system routerboard print' do |cfg|
18
- cfg = cfg.each_line.grep(/(model|firmware-type|current-firmware|serial-number):/).join
17
+ cmd '/system resource print' do |cfg|
18
+ cfg = cfg.each_line.grep(/(version|factory-software|total-memory|cpu|cpu-count|total-hdd-space|architecture-name|board-name|platform):/).join
19
19
  comment cfg
20
20
  end
21
21
 
@@ -4,12 +4,29 @@ class SAOS < Oxidized::Model
4
4
  # Ciena SAOS switch
5
5
  # used for 6.x devices
6
6
 
7
- comment '! '
7
+ comment '! '
8
+ prompt /^[\w-]+\*?>\s?/
8
9
 
9
10
  cmd :all do |cfg|
11
+ cfg.gsub! /(Waiting for )(accounting|authorization).*\n/, '' # Remove TACACS errors
10
12
  cfg.cut_both
11
13
  end
12
14
 
15
+ cmd 'chassis show device-id power' do |cfg|
16
+ comment cfg
17
+ end
18
+
19
+ cmd 'software show' do |cfg|
20
+ cfg.gsub! /^\| Bank status.*/, '| Bank status : <removed> |'
21
+ comment cfg
22
+ end
23
+
24
+ cmd 'port xcvr show' do |cfg|
25
+ cfg.gsub! /^SHELL PARSER FAILURE.*/, '' # Ignore command failure
26
+ cfg.gsub! /(\s\|.{10}\|)(Ena\s\s|\s\sDis|UCTF\s)(.*)/, '\1 \3' # Remove transient operational state
27
+ comment cfg
28
+ end
29
+
13
30
  cmd 'configuration show' do |cfg|
14
31
  cfg.gsub! /^! Created: [^\n]*\n/, ''
15
32
  cfg.gsub! /^! On terminal: [^\n]*\n/, ''
@@ -0,0 +1,22 @@
1
+ class SikluMHTG < Oxidized::Model
2
+ using Refinements
3
+
4
+ # Siklu MultiHaul TG#
5
+ # Requires source to define the model as SikluMHTG #
6
+
7
+ prompt /^\r?MH-[TN]\d{3}[\@][\w]{2,8}>$/
8
+
9
+ expect /--More--/ do |data, re|
10
+ send ' '
11
+ data.sub re, ''
12
+ end
13
+
14
+ cmd 'show startup' do |cfg|
15
+ cfg.gsub! /[\b]|\e\[A|\e\[2K/, ''
16
+ cfg.cut_both
17
+ end
18
+
19
+ cfg :ssh do
20
+ pre_logout 'quit'
21
+ end
22
+ end
@@ -3,8 +3,14 @@ class SonicOS < Oxidized::Model
3
3
 
4
4
  # Applies to Sonicwall NSA series firewalls
5
5
 
6
- prompt /^\w+@\w+[>]\(?.+\)?\s?/
7
- comment '! '
6
+ prompt /^\w+@[\w\-]+[>]\(?.+\)?\s?/
7
+ comment '! '
8
+
9
+ # Accept policiy message (see Issue #3339). Tested on 6.5 and 7.1
10
+ expect /Accept The Policy Banner \(yes\)\?\r\nyes: $/ do |data, re|
11
+ send "yes\n"
12
+ data.sub re, ''
13
+ end
8
14
 
9
15
  cmd :all do |cfg|
10
16
  cfg.each_line.to_a[1..-2].join
@@ -58,6 +58,7 @@ class TPLink < Oxidized::Model
58
58
  if vars(:enable) == true
59
59
  cmd "enable"
60
60
  elsif vars(:enable)
61
+ cmd "enable", /^[pP]assword:/
61
62
  cmd vars(:enable)
62
63
  end
63
64
  end
@@ -0,0 +1,46 @@
1
+ class UPLINKOLT < Oxidized::Model
2
+ prompt /^([\w.@()-]+[#>]\s?)$/
3
+ comment '! '
4
+
5
+ cmd :all do |cfg|
6
+ cfg.gsub! /^% Invalid input detected at '\^' marker\.$|^\s+\^$/, ''
7
+ cfg.gsub!(/^show running-config$/, '')
8
+ cfg.gsub!(/^.*\s*#\s*$/, '')
9
+ # Remove leading and trailing whitespace
10
+ cfg.strip!
11
+ # Remove empty lines
12
+ cfg.gsub!(/^\s*$/, '')
13
+ cfg
14
+ end
15
+
16
+ cmd 'configure terminal' do
17
+ # Enter configure terminal mode
18
+ cmd 'show version' do |cfg|
19
+ cfg.gsub! /^show version/, ''
20
+ comment cfg
21
+ end
22
+ end
23
+
24
+ cmd 'show running-config' do |cfg|
25
+ cfg.gsub! /^Current configuration:/, ''
26
+ cfg
27
+ end
28
+
29
+ cfg :telnet, :ssh do
30
+ username /^Login:/i
31
+ password /^Password:/i
32
+ # preferred way to handle additional passwords
33
+ post_login do
34
+ if vars(:enable) == true
35
+ cmd "enable"
36
+ elsif vars(:enable)
37
+ cmd "enable", /^[pP]assword:/
38
+ cmd vars(:enable)
39
+ end
40
+ end
41
+ post_login 'terminal length 0'
42
+ pre_logout 'exit'
43
+ pre_logout 'disable'
44
+ pre_logout 'exit'
45
+ end
46
+ end
@@ -3,7 +3,7 @@ class Vyatta < Oxidized::Model
3
3
 
4
4
  # Brocade Vyatta / VyOS model #
5
5
 
6
- prompt /@.*?:~\$\s/
6
+ prompt /@.*(:~\$|>)\s/
7
7
 
8
8
  cmd :all do |cfg|
9
9
  cfg.lines.to_a[1..-2].join
@@ -14,7 +14,7 @@ class Vyatta < Oxidized::Model
14
14
  cfg.gsub! /plaintext-password (\S+).*/, 'plaintext-password <secret removed>'
15
15
  cfg.gsub! /password (\S+).*/, 'password <secret removed>'
16
16
  cfg.gsub! /pre-shared-secret (\S+).*/, 'pre-shared-secret <secret removed>'
17
- cfg.gsub! /community (\S+) {/, 'community <hidden> {'
17
+ cfg.gsub! /community (\S+)/, 'community <hidden>'
18
18
  cfg.gsub! /private-key (\S+).*/, 'private-key <secret removed>'
19
19
  cfg.gsub! /preshared-key (\S+).*/, 'preshared-key <secret removed>'
20
20
  cfg
@@ -12,6 +12,13 @@ class XOS < Oxidized::Model
12
12
  cfg.each_line.to_a[1..-2].map { |line| line.delete("\r").rstrip }.join("\n") + "\n"
13
13
  end
14
14
 
15
+ cmd :secret do |cfg|
16
+ cfg.gsub! /^(configure (radius|radius-accounting) (netlogin|mgmt-access) (primary|secondary) shared-secret encrypted).+/, '\\1 <secret hidden>'
17
+ cfg.gsub! /^(configure account admin encrypted).+/, '\\1 <secret hidden>'
18
+ cfg.gsub! /^(create account (admin|user) (.+) encrypted).+/, '\\1 <secret hidden>'
19
+ cfg
20
+ end
21
+
15
22
  cmd 'show version' do |cfg|
16
23
  comment cfg
17
24
  end
data/lib/oxidized/node.rb CHANGED
@@ -80,6 +80,8 @@ module Oxidized
80
80
  @err_reason = err.message.to_s
81
81
  false
82
82
  rescue StandardError => e
83
+ # Send a message in debug mode in case we are not able to create a crashfile
84
+ Oxidized.logger.send(:debug, '%s raised %s with msg "%s", creating crashfile' % [ip, e.class, e.message])
83
85
  crashdir = Oxidized.config.crash.directory
84
86
  crashfile = Oxidized.config.crash.hostnames? ? name : ip.to_s
85
87
  FileUtils.mkdir_p(crashdir) unless File.directory?(crashdir)
@@ -198,33 +200,43 @@ module Oxidized
198
200
  end
199
201
 
200
202
  def resolve_key(key, opt, global = nil)
201
- # resolve key, first get global, then get group then get node config
203
+ # resolve key: the priority is as follows: node -> group specific model -> group -> model -> global passed -> global
204
+ # where node has the highest priority (= if defined, overwrites other values)
202
205
  key_sym = key.to_sym
203
206
  key_str = key.to_s
204
- value = global
205
- Oxidized.logger.debug "node.rb: resolving node key '#{key}', with passed global value of '#{value}' and node value '#{opt[key_sym]}'"
207
+ model_name = @model.class.name.to_s.downcase
208
+ Oxidized.logger.debug "node.rb: resolving node key '#{key}', with passed global value of '#{global}' and node value '#{opt[key_sym]}'"
206
209
 
207
- # global
208
- if (not value) && Oxidized.config.has_key?(key_str)
209
- value = Oxidized.config[key_str]
210
- Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '#{value}' from global"
211
- end
210
+ # Node
211
+ if opt[key_sym]
212
+ value = opt[key_sym]
213
+ Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '#{value}' from node"
212
214
 
213
- # group
214
- if Oxidized.config.groups.has_key?(@group) && Oxidized.config.groups[@group].has_key?(key_str)
215
+ # Group specific model
216
+ elsif Oxidized.config.groups.has_key?(@group) && Oxidized.config.groups[@group].models.has_key?(model_name) && Oxidized.config.groups[@group].models[model_name].has_key?(key_str)
217
+ value = Oxidized.config.groups[@group].models[model_name][key_str]
218
+ Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '#{value}' from model in group"
219
+
220
+ # Group
221
+ elsif Oxidized.config.groups.has_key?(@group) && Oxidized.config.groups[@group].has_key?(key_str)
215
222
  value = Oxidized.config.groups[@group][key_str]
216
223
  Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '#{value}' from group"
217
- end
218
224
 
219
- # model
220
- if Oxidized.config.models.has_key?(@model.class.name.to_s.downcase) && Oxidized.config.models[@model.class.name.to_s.downcase].has_key?(key_str)
221
- value = Oxidized.config.models[@model.class.name.to_s.downcase][key_str]
225
+ # Model
226
+ elsif Oxidized.config.models.has_key?(model_name) && Oxidized.config.models[model_name].has_key?(key_str)
227
+ value = Oxidized.config.models[model_name][key_str]
222
228
  Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '#{value}' from model"
223
- end
224
229
 
225
- # node
226
- value = opt[key_sym] || value
227
- Oxidized.logger.debug "node.rb: returning node key '#{key}' with value '#{value}'"
230
+ # Global passed
231
+ elsif global
232
+ value = global
233
+ Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '#{value}' from passed global value"
234
+
235
+ # Global
236
+ elsif Oxidized.config.has_key?(key_str)
237
+ value = Oxidized.config[key_str]
238
+ Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '#{value}' from global"
239
+ end
228
240
  value
229
241
  end
230
242
 
@@ -61,6 +61,9 @@ module Oxidized
61
61
  end
62
62
  end
63
63
 
64
+ # Returns the configuration of group/node_name
65
+ #
66
+ # #fetch is called by oxidzed-web
64
67
  def fetch(node_name, group)
65
68
  yield_node_output(node_name) do |node, output|
66
69
  output.fetch node, group
@@ -69,7 +72,7 @@ module Oxidized
69
72
 
70
73
  # @param node [String] name of the node moved into the head of array
71
74
  def next(node, opt = {})
72
- return unless waiting.find_node_index(node)
75
+ return if running.find_index(node)
73
76
 
74
77
  with_lock do
75
78
  n = del node
@@ -98,6 +101,9 @@ module Oxidized
98
101
  find_index(node) || raise(NodeNotFound, "unable to find '#{node}'")
99
102
  end
100
103
 
104
+ # Returns all stored versions of group/node_name
105
+ #
106
+ # Called by oxidized-web
101
107
  def version(node_name, group)
102
108
  yield_node_output(node_name) do |node, output|
103
109
  output.version node, group
@@ -116,6 +122,10 @@ module Oxidized
116
122
  end
117
123
  end
118
124
 
125
+ def find_index(node)
126
+ index { |e| [e.name, e.ip].include? node }
127
+ end
128
+
119
129
  private
120
130
 
121
131
  def initialize(opts = {})
@@ -133,10 +143,6 @@ module Oxidized
133
143
  @mutex.synchronize(...)
134
144
  end
135
145
 
136
- def find_index(node)
137
- index { |e| [e.name, e.ip].include? node }
138
- end
139
-
140
146
  # @param node node which is removed from nodes list
141
147
  # @return [Node] deleted node
142
148
  def del(node)
@@ -179,6 +185,8 @@ module Oxidized
179
185
  def yield_node_output(node_name)
180
186
  with_lock do
181
187
  node = find { |n| n.name == node_name }
188
+ raise(NodeNotFound, "unable to find '#{node_name}'") if node.nil?
189
+
182
190
  output = node.output.new
183
191
  raise NotSupported unless output.respond_to? :fetch
184
192
 
@@ -1,55 +1,58 @@
1
1
  module Oxidized
2
- class OxidizedFile < Output
3
- require 'fileutils'
2
+ module Output
3
+ # ruby's File class must be accessed with ::File to avoid name conflicts
4
+ class File < Output
5
+ require 'fileutils'
4
6
 
5
- attr_reader :commitref
7
+ attr_reader :commitref
6
8
 
7
- def initialize
8
- super
9
- @cfg = Oxidized.config.output.file
10
- end
9
+ def initialize
10
+ super
11
+ @cfg = Oxidized.config.output.file
12
+ end
11
13
 
12
- def setup
13
- return unless @cfg.empty?
14
+ def setup
15
+ return unless @cfg.empty?
14
16
 
15
- Oxidized.asetus.user.output.file.directory = File.join(Config::ROOT, 'configs')
16
- Oxidized.asetus.save :user
17
- raise NoConfig, 'no output file config, edit ~/.config/oxidized/config'
18
- end
17
+ Oxidized.asetus.user.output.file.directory = ::File.join(Config::ROOT, 'configs')
18
+ Oxidized.asetus.save :user
19
+ raise NoConfig, "no output file config, edit #{Oxidized::Config.configfile}"
20
+ end
19
21
 
20
- def store(node, outputs, opt = {})
21
- file = File.expand_path @cfg.directory
22
- file = File.join File.dirname(file), opt[:group] if opt[:group]
23
- FileUtils.mkdir_p file
24
- file = File.join file, node
25
- File.write(file, outputs.to_cfg)
26
- @commitref = file
27
- end
22
+ def store(node, outputs, opt = {})
23
+ file = ::File.expand_path @cfg.directory
24
+ file = ::File.join ::File.dirname(file), opt[:group] if opt[:group]
25
+ FileUtils.mkdir_p file
26
+ file = ::File.join file, node
27
+ ::File.write(file, outputs.to_cfg)
28
+ @commitref = file
29
+ end
28
30
 
29
- def fetch(node, group)
30
- cfg_dir = File.expand_path @cfg.directory
31
- node_name = node.name
32
-
33
- if group # group is explicitly defined by user
34
- cfg_dir = File.join File.dirname(cfg_dir), group
35
- File.read File.join(cfg_dir, node_name)
36
- elsif File.exist? File.join(cfg_dir, node_name) # node configuration file is stored on base directory
37
- File.read File.join(cfg_dir, node_name)
38
- else
39
- path = Dir.glob(File.join(File.dirname(cfg_dir), '**', node_name)).first # fetch node in all groups
40
- File.read path
31
+ def fetch(node, group)
32
+ cfg_dir = ::File.expand_path @cfg.directory
33
+ node_name = node.name
34
+
35
+ if group # group is explicitly defined by user
36
+ cfg_dir = ::File.join ::File.dirname(cfg_dir), group
37
+ ::File.read ::File.join(cfg_dir, node_name)
38
+ elsif ::File.exist? ::File.join(cfg_dir, node_name) # node configuration file is stored on base directory
39
+ ::File.read ::File.join(cfg_dir, node_name)
40
+ else
41
+ path = Dir.glob(::File.join(::File.dirname(cfg_dir), '**', node_name)).first # fetch node in all groups
42
+ ::File.read path
43
+ end
44
+ rescue Errno::ENOENT
45
+ nil
41
46
  end
42
- rescue Errno::ENOENT
43
- nil
44
- end
45
47
 
46
- def version(_node, _group)
47
- # not supported
48
- []
49
- end
48
+ def version(_node, _group)
49
+ # not supported
50
+ []
51
+ end
50
52
 
51
- def get_version(_node, _group, _oid)
52
- 'not supported'
53
+ def get_version(_node, _group, _oid)
54
+ 'not supported'
55
+ end
53
56
  end
54
57
  end
55
58
  end