oxidized 0.20.0 → 0.28.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (222) hide show
  1. checksums.yaml +5 -5
  2. data/.codeclimate.yml +4 -0
  3. data/.github/PULL_REQUEST_TEMPLATE.md +12 -0
  4. data/.github/no-response.yml +13 -0
  5. data/.github/workflows/publishdocker.yml +13 -0
  6. data/.gitignore +4 -0
  7. data/.rubocop.yml +73 -0
  8. data/.rubocop_todo.yml +120 -0
  9. data/.travis.yml +6 -1
  10. data/CHANGELOG.md +693 -243
  11. data/Dockerfile +27 -19
  12. data/LICENSE +201 -0
  13. data/README.md +234 -913
  14. data/Rakefile +48 -7
  15. data/TODO.md +29 -23
  16. data/bin/console +1 -1
  17. data/bin/oxidized +6 -5
  18. data/docs/Configuration.md +313 -0
  19. data/docs/Creating-Models.md +140 -0
  20. data/docs/Hooks.md +274 -0
  21. data/docs/Model-Notes/AireOS.md +11 -0
  22. data/docs/Model-Notes/ArbOS.md +11 -0
  23. data/docs/Model-Notes/Comware.md +13 -0
  24. data/docs/Model-Notes/Cumulus.md +40 -0
  25. data/docs/Model-Notes/EOS.md +12 -0
  26. data/docs/Model-Notes/IOS.md +29 -0
  27. data/docs/Model-Notes/JunOS.md +33 -0
  28. data/docs/Model-Notes/LinuxGeneric.md +24 -0
  29. data/docs/Model-Notes/Netgear.md +87 -0
  30. data/docs/Model-Notes/Nokia.md +9 -0
  31. data/docs/Model-Notes/README.md +24 -0
  32. data/docs/Model-Notes/SmartAX-Huawei.md +35 -0
  33. data/docs/Model-Notes/VRP-Huawei.md +34 -0
  34. data/docs/Model-Notes/Viptela.md +12 -0
  35. data/docs/Model-Notes/XGS4600-Zyxel.md +36 -0
  36. data/docs/Outputs.md +190 -0
  37. data/docs/Ruby-API.md +199 -0
  38. data/docs/Sources.md +171 -0
  39. data/docs/Supported-OS-Types.md +227 -0
  40. data/docs/Troubleshooting.md +66 -0
  41. data/extra/nagios_check_failing_nodes.rb +9 -2
  42. data/extra/oxidized-report-git-commits +21 -40
  43. data/extra/oxidized-ubuntu.haproxy +45 -0
  44. data/extra/oxidized.logrotate +7 -0
  45. data/extra/oxidized.service +13 -0
  46. data/extra/rest_client.rb +7 -10
  47. data/extra/syslog.rb +47 -42
  48. data/lib/oxidized/cli.rb +41 -31
  49. data/lib/oxidized/config/vars.rb +9 -14
  50. data/lib/oxidized/config.rb +20 -13
  51. data/lib/oxidized/core.rb +8 -10
  52. data/lib/oxidized/hook/awssns.rb +6 -7
  53. data/lib/oxidized/hook/ciscosparkdiff.rb +43 -0
  54. data/lib/oxidized/hook/exec.rb +19 -24
  55. data/lib/oxidized/hook/githubrepo.rb +17 -17
  56. data/lib/oxidized/hook/noophook.rb +1 -1
  57. data/lib/oxidized/hook/slackdiff.rb +32 -19
  58. data/lib/oxidized/hook/xmppdiff.rb +59 -0
  59. data/lib/oxidized/hook.rb +63 -64
  60. data/lib/oxidized/input/cli.rb +22 -12
  61. data/lib/oxidized/input/exec.rb +28 -0
  62. data/lib/oxidized/input/ftp.rb +16 -15
  63. data/lib/oxidized/input/http.rb +72 -0
  64. data/lib/oxidized/input/input.rb +6 -6
  65. data/lib/oxidized/input/ssh.rb +64 -56
  66. data/lib/oxidized/input/telnet.rb +59 -102
  67. data/lib/oxidized/input/tftp.rb +9 -10
  68. data/lib/oxidized/jobs.rb +9 -10
  69. data/lib/oxidized/manager.rb +42 -44
  70. data/lib/oxidized/model/acos.rb +19 -20
  71. data/lib/oxidized/model/acsw.rb +62 -0
  72. data/lib/oxidized/model/adtran.rb +26 -0
  73. data/lib/oxidized/model/aen.rb +19 -0
  74. data/lib/oxidized/model/aireos.rb +9 -10
  75. data/lib/oxidized/model/airfiber.rb +22 -0
  76. data/lib/oxidized/model/alteonos.rb +58 -0
  77. data/lib/oxidized/model/alvarion.rb +0 -4
  78. data/lib/oxidized/model/aos.rb +11 -5
  79. data/lib/oxidized/model/aos7.rb +6 -7
  80. data/lib/oxidized/model/aosw.rb +30 -27
  81. data/lib/oxidized/model/apc_aos.rb +2 -5
  82. data/lib/oxidized/model/arbos.rb +26 -0
  83. data/lib/oxidized/model/aricentiss.rb +49 -0
  84. data/lib/oxidized/model/asa.rb +61 -22
  85. data/lib/oxidized/model/asyncos.rb +46 -0
  86. data/lib/oxidized/model/audiocodes.rb +28 -0
  87. data/lib/oxidized/model/audiocodesmp.rb +28 -0
  88. data/lib/oxidized/model/awplus.rb +84 -0
  89. data/lib/oxidized/model/axos.rb +16 -0
  90. data/lib/oxidized/model/boss.rb +77 -0
  91. data/lib/oxidized/model/br6910.rb +42 -45
  92. data/lib/oxidized/model/c4cmts.rb +6 -10
  93. data/lib/oxidized/model/cambium.rb +23 -0
  94. data/lib/oxidized/model/casa.rb +1 -1
  95. data/lib/oxidized/model/catos.rb +1 -3
  96. data/lib/oxidized/model/cisconga.rb +1 -3
  97. data/lib/oxidized/model/ciscosma.rb +42 -0
  98. data/lib/oxidized/model/ciscosmb.rb +30 -10
  99. data/lib/oxidized/model/ciscovpn3k.rb +11 -0
  100. data/lib/oxidized/model/cnos.rb +33 -0
  101. data/lib/oxidized/model/comnetms.rb +43 -0
  102. data/lib/oxidized/model/comtrol.rb +41 -0
  103. data/lib/oxidized/model/comware.rb +28 -16
  104. data/lib/oxidized/model/coriant8600.rb +3 -5
  105. data/lib/oxidized/model/coriantgroove.rb +26 -0
  106. data/lib/oxidized/model/corianttmos.rb +1 -3
  107. data/lib/oxidized/model/cumulus.rb +60 -49
  108. data/lib/oxidized/model/datacom.rb +1 -4
  109. data/lib/oxidized/model/dcnos.rb +46 -0
  110. data/lib/oxidized/model/dellx.rb +76 -0
  111. data/lib/oxidized/model/dlink.rb +5 -4
  112. data/lib/oxidized/model/dnos.rb +11 -5
  113. data/lib/oxidized/model/eciapollo.rb +34 -0
  114. data/lib/oxidized/model/edgecos.rb +49 -0
  115. data/lib/oxidized/model/edgeos.rb +12 -5
  116. data/lib/oxidized/model/edgeswitch.rb +2 -4
  117. data/lib/oxidized/model/enterasys.rb +28 -0
  118. data/lib/oxidized/model/eos.rb +8 -8
  119. data/lib/oxidized/model/fabricos.rb +4 -6
  120. data/lib/oxidized/model/fastiron.rb +66 -0
  121. data/lib/oxidized/model/fiberdriver.rb +2 -2
  122. data/lib/oxidized/model/firebrick.rb +31 -0
  123. data/lib/oxidized/model/firelinuxos.rb +41 -0
  124. data/lib/oxidized/model/firewareos.rb +3 -6
  125. data/lib/oxidized/model/fortios.rb +31 -19
  126. data/lib/oxidized/model/ftos.rb +8 -5
  127. data/lib/oxidized/model/fujitsupy.rb +5 -7
  128. data/lib/oxidized/model/gaiaos.rb +7 -11
  129. data/lib/oxidized/model/gcombnps.rb +84 -0
  130. data/lib/oxidized/model/grandstream.rb +9 -0
  131. data/lib/oxidized/model/hatteras.rb +9 -6
  132. data/lib/oxidized/model/hirschmann.rb +39 -0
  133. data/lib/oxidized/model/hpebladesystem.rb +20 -18
  134. data/lib/oxidized/model/hpemsa.rb +10 -0
  135. data/lib/oxidized/model/hpmsm.rb +84 -0
  136. data/lib/oxidized/model/ibos.rb +55 -0
  137. data/lib/oxidized/model/icotera.rb +27 -0
  138. data/lib/oxidized/model/ios.rb +63 -70
  139. data/lib/oxidized/model/iosxe.rb +5 -0
  140. data/lib/oxidized/model/iosxr.rb +2 -3
  141. data/lib/oxidized/model/ipos.rb +10 -6
  142. data/lib/oxidized/model/ironware.rb +20 -19
  143. data/lib/oxidized/model/isam.rb +5 -6
  144. data/lib/oxidized/model/junos.rb +9 -11
  145. data/lib/oxidized/model/linuxgeneric.rb +74 -0
  146. data/lib/oxidized/model/masteros.rb +3 -6
  147. data/lib/oxidized/model/mlnxos.rb +9 -10
  148. data/lib/oxidized/model/model.rb +72 -46
  149. data/lib/oxidized/model/mtrlrfs.rb +1 -4
  150. data/lib/oxidized/model/ndms.rb +23 -0
  151. data/lib/oxidized/model/netgear.rb +35 -15
  152. data/lib/oxidized/model/netonix.rb +2 -2
  153. data/lib/oxidized/model/netscaler.rb +6 -3
  154. data/lib/oxidized/model/nos.rb +5 -7
  155. data/lib/oxidized/model/nsxconfig.rb +22 -0
  156. data/lib/oxidized/model/nsxfirewall.rb +22 -0
  157. data/lib/oxidized/model/nxos.rb +13 -3
  158. data/lib/oxidized/model/oneos.rb +15 -9
  159. data/lib/oxidized/model/openbsd.rb +63 -0
  160. data/lib/oxidized/model/opengear.rb +3 -5
  161. data/lib/oxidized/model/openwrt.rb +78 -0
  162. data/lib/oxidized/model/opnsense.rb +19 -0
  163. data/lib/oxidized/model/os10.rb +46 -0
  164. data/lib/oxidized/model/outputs.rb +5 -7
  165. data/lib/oxidized/model/panos.rb +11 -12
  166. data/lib/oxidized/model/pfsense.rb +11 -6
  167. data/lib/oxidized/model/planet.rb +14 -17
  168. data/lib/oxidized/model/powerconnect.rb +24 -19
  169. data/lib/oxidized/model/procurve.rb +43 -11
  170. data/lib/oxidized/model/purityos.rb +12 -0
  171. data/lib/oxidized/model/qtech.rb +41 -0
  172. data/lib/oxidized/model/quantaos.rb +4 -6
  173. data/lib/oxidized/model/raisecom.rb +19 -0
  174. data/lib/oxidized/model/routeros.rb +26 -8
  175. data/lib/oxidized/model/saos.rb +1 -2
  176. data/lib/oxidized/model/screenos.rb +8 -11
  177. data/lib/oxidized/model/sgos.rb +45 -0
  178. data/lib/oxidized/model/siklu.rb +1 -3
  179. data/lib/oxidized/model/slxos.rb +59 -0
  180. data/lib/oxidized/model/smartax.rb +25 -0
  181. data/lib/oxidized/model/sonicos.rb +51 -0
  182. data/lib/oxidized/model/speedtouch.rb +34 -0
  183. data/lib/oxidized/model/sros.rb +96 -0
  184. data/lib/oxidized/model/stoneos.rb +32 -0
  185. data/lib/oxidized/model/supermicro.rb +6 -41
  186. data/lib/oxidized/model/tdre.rb +30 -0
  187. data/lib/oxidized/model/telco.rb +24 -0
  188. data/lib/oxidized/model/timos.rb +6 -114
  189. data/lib/oxidized/model/tmos.rb +6 -3
  190. data/lib/oxidized/model/tplink.rb +11 -11
  191. data/lib/oxidized/model/trango.rb +21 -42
  192. data/lib/oxidized/model/ucs.rb +30 -0
  193. data/lib/oxidized/model/viptela.rb +29 -0
  194. data/lib/oxidized/model/voltaire.rb +9 -12
  195. data/lib/oxidized/model/voss.rb +17 -6
  196. data/lib/oxidized/model/vrp.rb +11 -6
  197. data/lib/oxidized/model/vyatta.rb +8 -6
  198. data/lib/oxidized/model/weos.rb +20 -0
  199. data/lib/oxidized/model/xos.rb +20 -8
  200. data/lib/oxidized/model/zhoneolt.rb +2 -2
  201. data/lib/oxidized/model/zynos.rb +1 -3
  202. data/lib/oxidized/model/zynoscli.rb +36 -0
  203. data/lib/oxidized/model/zynosgs.rb +38 -0
  204. data/lib/oxidized/node/stats.rb +33 -8
  205. data/lib/oxidized/node.rb +86 -95
  206. data/lib/oxidized/nodes.rb +48 -44
  207. data/lib/oxidized/output/file.rb +32 -37
  208. data/lib/oxidized/output/git.rb +138 -153
  209. data/lib/oxidized/output/gitcrypt.rb +228 -242
  210. data/lib/oxidized/output/http.rb +35 -34
  211. data/lib/oxidized/output/output.rb +2 -3
  212. data/lib/oxidized/source/csv.rb +50 -44
  213. data/lib/oxidized/source/http.rb +58 -58
  214. data/lib/oxidized/source/source.rb +9 -10
  215. data/lib/oxidized/source/sql.rb +47 -45
  216. data/lib/oxidized/string.rb +18 -14
  217. data/lib/oxidized/version.rb +17 -1
  218. data/lib/oxidized/worker.rb +72 -33
  219. data/oxidized.gemspec +20 -19
  220. metadata +180 -36
  221. data/.ruby-version +0 -1
  222. data/Gemfile.lock +0 -44
@@ -1,244 +1,230 @@
1
1
  module Oxidized
2
- class GitCrypt < Output
3
- class GitCryptError < OxidizedError; end
4
- begin
5
- require 'git'
6
- rescue LoadError
7
- raise OxidizedError, 'git not found: sudo gem install ruby-git'
8
- end
9
-
10
- attr_reader :commitref
11
-
12
- def initialize
13
- @cfg = Oxidized.config.output.gitcrypt
14
- @gitcrypt_cmd = "/usr/bin/git-crypt"
15
- @gitcrypt_init = @gitcrypt_cmd + " init"
16
- @gitcrypt_unlock = @gitcrypt_cmd + " unlock"
17
- @gitcrypt_lock = @gitcrypt_cmd + " lock"
18
- @gitcrypt_adduser = @gitcrypt_cmd + " add-gpg-user --trusted "
19
- end
20
-
21
- def setup
22
- if @cfg.empty?
23
- Oxidized.asetus.user.output.gitcrypt.user = 'Oxidized'
24
- Oxidized.asetus.user.output.gitcrypt.email = 'o@example.com'
25
- Oxidized.asetus.user.output.gitcrypt.repo = File.join(Config::Root, 'oxidized.git')
26
- Oxidized.asetus.save :user
27
- raise NoConfig, 'no output git config, edit ~/.config/oxidized/config'
28
- end
29
-
30
- if @cfg.repo.respond_to?(:each)
31
- @cfg.repo.each do |group, repo|
32
- @cfg.repo["#{group}="] = File.expand_path repo
33
- end
34
- else
35
- @cfg.repo = File.expand_path @cfg.repo
36
- end
37
- end
38
-
39
- def crypt_init repo
40
- repo.chdir do
41
- system(@gitcrypt_init)
42
- @cfg.users.each do |user|
43
- system("#{@gitcrypt_adduser} #{user}")
44
- end
45
- File.write(".gitattributes", "* filter=git-crypt diff=git-crypt\n.gitattributes !filter !diff")
46
- repo.add(".gitattributes")
47
- repo.commit("Initial commit: crypt all config files")
48
- end
49
- end
50
-
51
- def lock repo
52
- repo.chdir do
53
- system(@gitcrypt_lock)
54
- end
55
- end
56
-
57
- def unlock repo
58
- repo.chdir do
59
- system(@gitcrypt_unlock)
60
- end
61
- end
62
-
63
- def store file, outputs, opt={}
64
- @msg = opt[:msg]
65
- @user = (opt[:user] or @cfg.user)
66
- @email = (opt[:email] or @cfg.email)
67
- @opt = opt
68
- @commitref = nil
69
- repo = @cfg.repo
70
-
71
- outputs.types.each do |type|
72
- type_cfg = ''
73
- type_repo = File.join(File.dirname(repo), type + '.git')
74
- outputs.type(type).each do |output|
75
- (type_cfg << output; next) if not output.name
76
- type_file = file + '--' + output.name
77
- if @cfg.type_as_directory?
78
- type_file = type + '/' + type_file
79
- type_repo = repo
80
- end
81
- update type_repo, type_file, output
82
- end
83
- update type_repo, file, type_cfg
84
- end
85
-
86
- update repo, file, outputs.to_cfg
87
- end
88
-
89
-
90
- def fetch node, group
91
- begin
92
- repo, path = yield_repo_and_path(node, group)
93
- repo = Git.open repo
94
- unlock repo
95
- index = repo.index
96
- # Empty repo ?
97
- empty = File.exists? index.path
98
- if empty
99
- raise 'Empty git repo'
100
- else
101
- File.read path
102
- end
103
- lock repo
104
- rescue
105
- 'node not found'
106
- end
107
- end
108
-
109
- # give a hash of all oid revision for the given node, and the date of the commit
110
- def version node, group
111
- begin
112
- repo, path = yield_repo_and_path(node, group)
113
-
114
- repo = Git.open repo
115
- unlock repo
116
- walker = repo.log.path(path)
117
- i = -1
118
- tab = []
119
- walker.each do |commit|
120
- hash = {}
121
- hash[:date] = commit.date.to_s
122
- hash[:oid] = commit.objectish
123
- hash[:author] = commit.author
124
- hash[:message] = commit.message
125
- tab[i += 1] = hash
126
- end
127
- walker.reset
128
- tab
129
- rescue
130
- 'node not found'
131
- end
132
- end
133
-
134
- #give the blob of a specific revision
135
- def get_version node, group, oid
136
- begin
137
- repo, path = yield_repo_and_path(node, group)
138
- repo = Git.open repo
139
- unlock repo
140
- repo.gtree(oid).files[path].contents
141
- rescue
142
- 'version not found'
143
- ensure
144
- lock repo
145
- end
146
- end
147
-
148
- #give a hash with the patch of a diff between 2 revision and the stats (added and deleted lines)
149
- def get_diff node, group, oid1, oid2
150
- begin
151
- diff_commits = nil
152
- repo, path = yield_repo_and_path(node, group)
153
- repo = Git.open repo
154
- unlock repo
155
- commit = repo.gcommit(oid1)
156
-
157
- if oid2
158
- commit_old = repo.gcommit(oid2)
159
- diff = repo.diff(commit_old, commit)
160
- stats = [diff.stats[:files][node.name][:insertions], diff.stats[:files][node.name][:deletions]]
161
- diff.each do |patch|
162
- if /#{node.name}\s+/.match(patch.patch.to_s.lines.first)
163
- diff_commits = {:patch => patch.patch.to_s, :stat => stats}
164
- break
165
- end
166
- end
167
- else
168
- stat = commit.parents[0].diff(commit).stats
169
- stat = [stat[:files][node.name][:insertions],stat[:files][node.name][:deletions]]
170
- patch = commit.parents[0].diff(commit).patch
171
- diff_commits = {:patch => patch, :stat => stat}
172
- end
173
- lock repo
174
- diff_commits
175
- rescue
176
- 'no diffs'
177
- ensure
178
- lock repo
179
- end
180
- end
181
-
182
- private
183
-
184
- def yield_repo_and_path(node, group)
185
- repo, path = node.repo, node.name
186
-
187
- if group and @cfg.single_repo?
188
- path = "#{group}/#{node.name}"
189
- end
190
-
191
- [repo, path]
192
- end
193
-
194
- def update repo, file, data
195
- return if data.empty?
196
-
197
- if @opt[:group]
198
- if @cfg.single_repo?
199
- file = File.join @opt[:group], file
200
- else
201
- repo = if repo.is_a?(::String)
202
- File.join File.dirname(repo), @opt[:group] + '.git'
203
- else
204
- repo[@opt[:group]]
205
- end
206
- end
207
- end
208
-
209
- begin
210
- update_repo repo, file, data, @msg, @user, @email
211
- rescue Git::GitExecuteError, ArgumentError => open_error
212
- Oxidized.logger.debug "open_error #{open_error} #{file}"
213
- begin
214
- grepo = Git.init repo
215
- crypt_init grepo
216
- rescue => create_error
217
- raise GitCryptError, "first '#{open_error.message}' was raised while opening git repo, then '#{create_error.message}' was while trying to create git repo"
218
- end
219
- retry
220
- end
221
- end
222
-
223
- def update_repo repo, file, data, msg, user, email
224
- grepo = Git.open repo
225
- grepo.config('user.name', user)
226
- grepo.config('user.email', email)
227
- grepo.chdir do
228
- unlock grepo
229
- File.write(file, data)
230
- grepo.add(file)
231
- if grepo.status[file].nil?
232
- grepo.commit(msg)
233
- @commitref = grepo.log(1).first.objectish
234
- true
235
- elsif !grepo.status[file].type.nil?
236
- grepo.commit(msg)
237
- @commitref = grepo.log(1).first.objectish
238
- true
239
- end
240
- lock grepo
241
- end
242
- end
243
- end
2
+ class GitCrypt < Output
3
+ class GitCryptError < OxidizedError; end
4
+ begin
5
+ require 'git'
6
+ rescue LoadError
7
+ raise OxidizedError, 'git not found: sudo gem install git'
8
+ end
9
+
10
+ attr_reader :commitref
11
+
12
+ def initialize
13
+ @cfg = Oxidized.config.output.gitcrypt
14
+ @gitcrypt_cmd = "/usr/bin/git-crypt"
15
+ @gitcrypt_init = @gitcrypt_cmd + " init"
16
+ @gitcrypt_unlock = @gitcrypt_cmd + " unlock"
17
+ @gitcrypt_lock = @gitcrypt_cmd + " lock"
18
+ @gitcrypt_adduser = @gitcrypt_cmd + " add-gpg-user --trusted "
19
+ end
20
+
21
+ def setup
22
+ if @cfg.empty?
23
+ Oxidized.asetus.user.output.gitcrypt.user = 'Oxidized'
24
+ Oxidized.asetus.user.output.gitcrypt.email = 'o@example.com'
25
+ Oxidized.asetus.user.output.gitcrypt.repo = File.join(Config::Root, 'oxidized.git')
26
+ Oxidized.asetus.save :user
27
+ raise NoConfig, 'no output git config, edit ~/.config/oxidized/config'
28
+ end
29
+
30
+ if @cfg.repo.respond_to?(:each)
31
+ @cfg.repo.each do |group, repo|
32
+ @cfg.repo["#{group}="] = File.expand_path repo
33
+ end
34
+ else
35
+ @cfg.repo = File.expand_path @cfg.repo
36
+ end
37
+ end
38
+
39
+ def crypt_init(repo)
40
+ repo.chdir do
41
+ system(@gitcrypt_init)
42
+ @cfg.users.each do |user|
43
+ system("#{@gitcrypt_adduser} #{user}")
44
+ end
45
+ File.write(".gitattributes", "* filter=git-crypt diff=git-crypt\n.gitattributes !filter !diff")
46
+ repo.add(".gitattributes")
47
+ repo.commit("Initial commit: crypt all config files")
48
+ end
49
+ end
50
+
51
+ def lock(repo)
52
+ repo.chdir do
53
+ system(@gitcrypt_lock)
54
+ end
55
+ end
56
+
57
+ def unlock(repo)
58
+ repo.chdir do
59
+ system(@gitcrypt_unlock)
60
+ end
61
+ end
62
+
63
+ def store(file, outputs, opt = {})
64
+ @msg = opt[:msg]
65
+ @user = (opt[:user] || @cfg.user)
66
+ @email = (opt[:email] || @cfg.email)
67
+ @opt = opt
68
+ @commitref = nil
69
+ repo = @cfg.repo
70
+
71
+ outputs.types.each do |type|
72
+ type_cfg = ''
73
+ type_repo = File.join(File.dirname(repo), type + '.git')
74
+ outputs.type(type).each do |output|
75
+ (type_cfg << output; next) unless output.name # rubocop:disable Style/Semicolon
76
+ type_file = file + '--' + output.name
77
+ if @cfg.type_as_directory?
78
+ type_file = type + '/' + type_file
79
+ type_repo = repo
80
+ end
81
+ update type_repo, type_file, output
82
+ end
83
+ update type_repo, file, type_cfg
84
+ end
85
+
86
+ update repo, file, outputs.to_cfg
87
+ end
88
+
89
+ def fetch(node, group)
90
+ repo, path = yield_repo_and_path(node, group)
91
+ repo = Git.open repo
92
+ unlock repo
93
+ index = repo.index
94
+ # Empty repo ?
95
+ raise 'Empty git repo' if File.exist?(index.path)
96
+
97
+ File.read path
98
+ lock repo
99
+ rescue StandardError
100
+ 'node not found'
101
+ end
102
+
103
+ # give a hash of all oid revision for the given node, and the date of the commit
104
+ def version(node, group)
105
+ repo, path = yield_repo_and_path(node, group)
106
+
107
+ repo = Git.open repo
108
+ unlock repo
109
+ walker = repo.log.path(path)
110
+ i = -1
111
+ tab = []
112
+ walker.each do |commit|
113
+ hash = {}
114
+ hash[:date] = commit.date.to_s
115
+ hash[:oid] = commit.objectish
116
+ hash[:author] = commit.author
117
+ hash[:message] = commit.message
118
+ tab[i += 1] = hash
119
+ end
120
+ walker.reset
121
+ tab
122
+ rescue StandardError
123
+ 'node not found'
124
+ end
125
+
126
+ # give the blob of a specific revision
127
+ def get_version(node, group, oid)
128
+ repo, path = yield_repo_and_path(node, group)
129
+ repo = Git.open repo
130
+ unlock repo
131
+ repo.gtree(oid).files[path].contents
132
+ rescue StandardError
133
+ 'version not found'
134
+ ensure
135
+ lock repo
136
+ end
137
+
138
+ # give a hash with the patch of a diff between 2 revision and the stats (added and deleted lines)
139
+ def get_diff(node, group, oid1, oid2)
140
+ diff_commits = nil
141
+ repo, _path = yield_repo_and_path(node, group)
142
+ repo = Git.open repo
143
+ unlock repo
144
+ commit = repo.gcommit(oid1)
145
+
146
+ if oid2
147
+ commit_old = repo.gcommit(oid2)
148
+ diff = repo.diff(commit_old, commit)
149
+ stats = [diff.stats[:files][node.name][:insertions], diff.stats[:files][node.name][:deletions]]
150
+ diff.each do |patch|
151
+ if /#{node.name}\s+/ =~ patch.patch.to_s.lines.first
152
+ diff_commits = { patch: patch.patch.to_s, stat: stats }
153
+ break
154
+ end
155
+ end
156
+ else
157
+ stat = commit.parents[0].diff(commit).stats
158
+ stat = [stat[:files][node.name][:insertions], stat[:files][node.name][:deletions]]
159
+ patch = commit.parents[0].diff(commit).patch
160
+ diff_commits = { patch: patch, stat: stat }
161
+ end
162
+ lock repo
163
+ diff_commits
164
+ rescue StandardError
165
+ 'no diffs'
166
+ ensure
167
+ lock repo
168
+ end
169
+
170
+ private
171
+
172
+ def yield_repo_and_path(node, group)
173
+ repo, path = node.repo, node.name
174
+
175
+ path = "#{group}/#{node.name}" if group && @cfg.single_repo?
176
+
177
+ [repo, path]
178
+ end
179
+
180
+ def update(repo, file, data)
181
+ return if data.empty?
182
+
183
+ if @opt[:group]
184
+ if @cfg.single_repo?
185
+ file = File.join @opt[:group], file
186
+ else
187
+ repo = if repo.is_a?(::String)
188
+ File.join File.dirname(repo), @opt[:group] + '.git'
189
+ else
190
+ repo[@opt[:group]]
191
+ end
192
+ end
193
+ end
194
+
195
+ begin
196
+ update_repo repo, file, data, @msg, @user, @email
197
+ rescue Git::GitExecuteError, ArgumentError => open_error
198
+ Oxidized.logger.debug "open_error #{open_error} #{file}"
199
+ begin
200
+ grepo = Git.init repo
201
+ crypt_init grepo
202
+ rescue StandardError => create_error
203
+ raise GitCryptError, "first '#{open_error.message}' was raised while opening git repo, then '#{create_error.message}' was while trying to create git repo"
204
+ end
205
+ retry
206
+ end
207
+ end
208
+
209
+ def update_repo(repo, file, data, msg, user, email)
210
+ grepo = Git.open repo
211
+ grepo.config('user.name', user)
212
+ grepo.config('user.email', email)
213
+ grepo.chdir do
214
+ unlock grepo
215
+ File.write(file, data)
216
+ grepo.add(file)
217
+ if grepo.status[file].nil?
218
+ grepo.commit(msg)
219
+ @commitref = grepo.log(1).first.objectish
220
+ true
221
+ elsif !grepo.status[file].type.nil?
222
+ grepo.commit(msg)
223
+ @commitref = grepo.log(1).first.objectish
224
+ true
225
+ end
226
+ lock grepo
227
+ end
228
+ end
229
+ end
244
230
  end
@@ -6,53 +6,54 @@ module Oxidized
6
6
  end
7
7
 
8
8
  def setup
9
- if @cfg.empty?
10
- CFGS.user.output.http.user = 'Oxidized'
11
- CFGS.user.output.http.pasword = 'secret'
12
- CFGS.user.output.http.url = 'http://localhost/web-api/oxidized'
13
- CFGS.save :user
14
- raise NoConfig, 'no output http config, edit ~/.config/oxidized/config'
15
- end
9
+ return unless @cfg.empty?
10
+
11
+ CFGS.user.output.http.user = 'Oxidized'
12
+ CFGS.user.output.http.pasword = 'secret'
13
+ CFGS.user.output.http.url = 'http://localhost/web-api/oxidized'
14
+ CFGS.save :user
15
+ raise NoConfig, 'no output http config, edit ~/.config/oxidized/config'
16
16
  end
17
+
17
18
  require "net/http"
18
19
  require "uri"
19
20
  require "json"
20
- def store node, outputs, opt={}
21
+
22
+ def store(node, outputs, opt = {})
21
23
  @commitref = nil
22
- json = JSON.pretty_generate(
23
- {
24
- 'msg' => opt[:msg],
25
- 'user' => opt[:user],
26
- 'email' => opt[:email],
27
- 'group' => opt[:group],
28
- 'node' => node,
29
- 'config' => outputs.to_cfg,
30
- # actually we need to also iterate outputs, for other types like in gitlab. But most people don't use 'type' functionality.
31
- }
32
- )
33
24
  uri = URI.parse @cfg.url
34
25
  http = Net::HTTP.new uri.host, uri.port
35
- #http.use_ssl = true if uri.scheme = 'https'
36
- req = Net::HTTP::Post.new(uri.request_uri, initheader = { 'Content-Type' => 'application/json'})
26
+ # http.use_ssl = true if uri.scheme = 'https'
27
+ req = Net::HTTP::Post.new(uri.request_uri, 'Content-Type' => 'application/json')
37
28
  req.basic_auth @cfg.user, @cfg.password
38
- req.body = json
29
+ req.body = generate_json(node, outputs, opt)
39
30
  response = http.request req
40
31
 
41
32
  case response.code.to_i
42
- when 200 || 201
43
- Oxidized.logger.info "Configuration http backup complete for #{node}"
44
- p [:success]
45
- when (400..499)
46
- Oxidized.logger.info "Configuration http backup for #{node} failed status: #{response.body}"
47
- p [:bad_request]
48
- when (500..599)
49
- p [:server_problems]
50
- Oxidized.logger.info "Configuration http backup for #{node} failed status: #{response.body}"
33
+ when 200 || 201
34
+ Oxidized.logger.info "Configuration http backup complete for #{node}"
35
+ p [:success]
36
+ when (400..499)
37
+ Oxidized.logger.info "Configuration http backup for #{node} failed status: #{response.body}"
38
+ p [:bad_request]
39
+ when (500..599)
40
+ p [:server_problems]
41
+ Oxidized.logger.info "Configuration http backup for #{node} failed status: #{response.body}"
51
42
  end
52
-
53
43
  end
54
44
 
45
+ private
46
+
47
+ def generate_json(node, outputs, opt)
48
+ JSON.pretty_generate(
49
+ 'msg' => opt[:msg],
50
+ 'user' => opt[:user],
51
+ 'email' => opt[:email],
52
+ 'group' => opt[:group],
53
+ 'node' => node,
54
+ 'config' => outputs.to_cfg
55
+ # actually we need to also iterate outputs, for other types like in gitlab. But most people don't use 'type' functionality.
56
+ )
57
+ end
55
58
  end
56
59
  end
57
-
58
-
@@ -2,9 +2,8 @@ module Oxidized
2
2
  class Output
3
3
  class NoConfig < OxidizedError; end
4
4
 
5
- def cfg_to_str cfg
6
- cfg.select{ |h| h[:type]=='cfg' }.map{ |h| h[:data] }.join
5
+ def cfg_to_str(cfg)
6
+ cfg.select { |h| h[:type] == 'cfg' }.map { |h| h[:data] }.join
7
7
  end
8
-
9
8
  end
10
9
  end