oxidized 0.21.0 → 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (170) hide show
  1. checksums.yaml +5 -5
  2. data/.github/no-response.yml +13 -0
  3. data/.gitignore +3 -0
  4. data/.rubocop.yml +37 -0
  5. data/.rubocop_todo.yml +714 -0
  6. data/.travis.yml +7 -1
  7. data/CHANGELOG.md +341 -243
  8. data/Dockerfile +44 -16
  9. data/LICENSE +201 -0
  10. data/README.md +114 -82
  11. data/Rakefile +19 -0
  12. data/TODO.md +29 -23
  13. data/bin/oxidized +1 -2
  14. data/docs/Configuration.md +71 -31
  15. data/docs/Creating-Models.md +78 -0
  16. data/docs/Hooks.md +145 -41
  17. data/docs/Model-Notes/AireOS.md +12 -0
  18. data/docs/Model-Notes/ArbOS.md +12 -0
  19. data/docs/Model-Notes/Comware.md +14 -0
  20. data/docs/Model-Notes/EOS.md +9 -0
  21. data/docs/Model-Notes/JunOS.md +34 -0
  22. data/docs/Model-Notes/Netgear.md +68 -0
  23. data/docs/Model-Notes/README.md +19 -0
  24. data/docs/{VRP-Huawei.md → Model-Notes/VRP-Huawei.md} +10 -2
  25. data/docs/Model-Notes/XGS4600-Zyxel.md +39 -0
  26. data/docs/Outputs.md +27 -28
  27. data/docs/Ruby-API.md +38 -18
  28. data/docs/Sources.md +78 -16
  29. data/docs/Supported-OS-Types.md +171 -148
  30. data/extra/oxidized.logrotate +7 -0
  31. data/extra/oxidized.service +1 -1
  32. data/extra/rest_client.rb +4 -5
  33. data/extra/syslog.rb +16 -16
  34. data/lib/oxidized/cli.rb +3 -3
  35. data/lib/oxidized/config.rb +7 -4
  36. data/lib/oxidized/core.rb +3 -3
  37. data/lib/oxidized/hook.rb +64 -65
  38. data/lib/oxidized/hook/awssns.rb +2 -3
  39. data/lib/oxidized/hook/ciscosparkdiff.rb +49 -0
  40. data/lib/oxidized/hook/exec.rb +5 -5
  41. data/lib/oxidized/hook/githubrepo.rb +20 -14
  42. data/lib/oxidized/hook/slackdiff.rb +38 -19
  43. data/lib/oxidized/hook/xmppdiff.rb +58 -0
  44. data/lib/oxidized/input/cli.rb +5 -6
  45. data/lib/oxidized/input/ftp.rb +8 -7
  46. data/lib/oxidized/input/http.rb +39 -0
  47. data/lib/oxidized/input/ssh.rb +24 -22
  48. data/lib/oxidized/input/telnet.rb +38 -32
  49. data/lib/oxidized/jobs.rb +3 -4
  50. data/lib/oxidized/manager.rb +9 -4
  51. data/lib/oxidized/model/acos.rb +15 -16
  52. data/lib/oxidized/model/acsw.rb +3 -8
  53. data/lib/oxidized/model/aen.rb +1 -2
  54. data/lib/oxidized/model/aireos.rb +3 -5
  55. data/lib/oxidized/model/alteonos.rb +16 -18
  56. data/lib/oxidized/model/alvarion.rb +0 -4
  57. data/lib/oxidized/model/aos.rb +2 -4
  58. data/lib/oxidized/model/aos7.rb +2 -3
  59. data/lib/oxidized/model/aosw.rb +13 -15
  60. data/lib/oxidized/model/apc_aos.rb +0 -3
  61. data/lib/oxidized/model/arbos.rb +26 -0
  62. data/lib/oxidized/model/aricentiss.rb +51 -0
  63. data/lib/oxidized/model/asa.rb +33 -35
  64. data/lib/oxidized/model/asyncos.rb +41 -44
  65. data/lib/oxidized/model/audiocodes.rb +4 -8
  66. data/lib/oxidized/model/awplus.rb +84 -0
  67. data/lib/oxidized/model/boss.rb +6 -5
  68. data/lib/oxidized/model/br6910.rb +43 -45
  69. data/lib/oxidized/model/c4cmts.rb +3 -5
  70. data/lib/oxidized/model/cambium.rb +22 -0
  71. data/lib/oxidized/model/catos.rb +0 -2
  72. data/lib/oxidized/model/cisconga.rb +1 -3
  73. data/lib/oxidized/model/ciscosma.rb +37 -40
  74. data/lib/oxidized/model/ciscosmb.rb +7 -4
  75. data/lib/oxidized/model/comnetms.rb +43 -0
  76. data/lib/oxidized/model/comware.rb +9 -9
  77. data/lib/oxidized/model/coriant8600.rb +3 -5
  78. data/lib/oxidized/model/coriantgroove.rb +3 -5
  79. data/lib/oxidized/model/corianttmos.rb +1 -3
  80. data/lib/oxidized/model/cumulus.rb +26 -32
  81. data/lib/oxidized/model/datacom.rb +0 -2
  82. data/lib/oxidized/model/dcnos.rb +46 -0
  83. data/lib/oxidized/model/dlink.rb +1 -1
  84. data/lib/oxidized/model/dnos.rb +9 -5
  85. data/lib/oxidized/model/edgecos.rb +45 -0
  86. data/lib/oxidized/model/edgeos.rb +5 -3
  87. data/lib/oxidized/model/edgeswitch.rb +1 -3
  88. data/lib/oxidized/model/enterasys.rb +1 -3
  89. data/lib/oxidized/model/eos.rb +6 -8
  90. data/lib/oxidized/model/fabricos.rb +3 -5
  91. data/lib/oxidized/model/firewareos.rb +2 -5
  92. data/lib/oxidized/model/fortios.rb +21 -17
  93. data/lib/oxidized/model/ftos.rb +2 -4
  94. data/lib/oxidized/model/fujitsupy.rb +2 -4
  95. data/lib/oxidized/model/gaiaos.rb +6 -10
  96. data/lib/oxidized/model/gcombnps.rb +82 -0
  97. data/lib/oxidized/model/hatteras.rb +8 -5
  98. data/lib/oxidized/model/hirschmann.rb +8 -10
  99. data/lib/oxidized/model/hpebladesystem.rb +19 -17
  100. data/lib/oxidized/model/hpemsa.rb +0 -3
  101. data/lib/oxidized/model/ios.rb +54 -55
  102. data/lib/oxidized/model/iosxe.rb +5 -0
  103. data/lib/oxidized/model/iosxr.rb +1 -3
  104. data/lib/oxidized/model/ipos.rb +1 -3
  105. data/lib/oxidized/model/ironware.rb +12 -15
  106. data/lib/oxidized/model/isam.rb +4 -5
  107. data/lib/oxidized/model/junos.rb +8 -7
  108. data/lib/oxidized/model/masteros.rb +1 -3
  109. data/lib/oxidized/model/mlnxos.rb +3 -4
  110. data/lib/oxidized/model/model.rb +15 -7
  111. data/lib/oxidized/model/mtrlrfs.rb +1 -4
  112. data/lib/oxidized/model/ndms.rb +24 -0
  113. data/lib/oxidized/model/netgear.rb +3 -4
  114. data/lib/oxidized/model/netscaler.rb +0 -2
  115. data/lib/oxidized/model/nos.rb +1 -3
  116. data/lib/oxidized/model/nxos.rb +13 -3
  117. data/lib/oxidized/model/oneos.rb +6 -8
  118. data/lib/oxidized/model/openbsd.rb +76 -0
  119. data/lib/oxidized/model/opengear.rb +3 -5
  120. data/lib/oxidized/model/openwrt.rb +77 -0
  121. data/lib/oxidized/model/opnsense.rb +19 -0
  122. data/lib/oxidized/model/outputs.rb +1 -3
  123. data/lib/oxidized/model/panos.rb +1 -2
  124. data/lib/oxidized/model/pfsense.rb +9 -5
  125. data/lib/oxidized/model/planet.rb +8 -12
  126. data/lib/oxidized/model/powerconnect.rb +6 -9
  127. data/lib/oxidized/model/procurve.rb +18 -4
  128. data/lib/oxidized/model/quantaos.rb +3 -5
  129. data/lib/oxidized/model/routeros.rb +3 -2
  130. data/lib/oxidized/model/saos.rb +0 -1
  131. data/lib/oxidized/model/screenos.rb +3 -5
  132. data/lib/oxidized/model/sgos.rb +2 -3
  133. data/lib/oxidized/model/siklu.rb +0 -2
  134. data/lib/oxidized/model/slxos.rb +59 -0
  135. data/lib/oxidized/model/sros.rb +117 -0
  136. data/lib/oxidized/model/stoneos.rb +32 -0
  137. data/lib/oxidized/model/supermicro.rb +6 -41
  138. data/lib/oxidized/model/timos.rb +6 -114
  139. data/lib/oxidized/model/tmos.rb +1 -3
  140. data/lib/oxidized/model/tplink.rb +7 -11
  141. data/lib/oxidized/model/trango.rb +6 -7
  142. data/lib/oxidized/model/ucs.rb +0 -1
  143. data/lib/oxidized/model/voltaire.rb +3 -6
  144. data/lib/oxidized/model/voss.rb +1 -2
  145. data/lib/oxidized/model/vrp.rb +4 -5
  146. data/lib/oxidized/model/vyatta.rb +6 -4
  147. data/lib/oxidized/model/weos.rb +1 -3
  148. data/lib/oxidized/model/xos.rb +6 -5
  149. data/lib/oxidized/model/zhoneolt.rb +2 -2
  150. data/lib/oxidized/model/zynos.rb +1 -3
  151. data/lib/oxidized/model/zynoscli.rb +36 -0
  152. data/lib/oxidized/node.rb +11 -11
  153. data/lib/oxidized/node/stats.rb +15 -2
  154. data/lib/oxidized/nodes.rb +8 -8
  155. data/lib/oxidized/output/file.rb +41 -42
  156. data/lib/oxidized/output/git.rb +113 -115
  157. data/lib/oxidized/output/gitcrypt.rb +241 -242
  158. data/lib/oxidized/output/http.rb +23 -27
  159. data/lib/oxidized/output/output.rb +1 -2
  160. data/lib/oxidized/source/csv.rb +44 -45
  161. data/lib/oxidized/source/http.rb +52 -49
  162. data/lib/oxidized/source/source.rb +6 -7
  163. data/lib/oxidized/source/sql.rb +55 -51
  164. data/lib/oxidized/string.rb +3 -4
  165. data/lib/oxidized/version.rb +17 -1
  166. data/lib/oxidized/worker.rb +12 -3
  167. data/oxidized.gemspec +19 -13
  168. metadata +139 -51
  169. data/.ruby-version +0 -1
  170. data/Gemfile.lock +0 -44
@@ -1,59 +1,58 @@
1
1
  module Oxidized
2
- class OxidizedFile < Output
3
- require 'fileutils'
2
+ class OxidizedFile < Output
3
+ require 'fileutils'
4
4
 
5
- attr_reader :commitref
5
+ attr_reader :commitref
6
6
 
7
- def initialize
8
- @cfg = Oxidized.config.output.file
9
- end
7
+ def initialize
8
+ @cfg = Oxidized.config.output.file
9
+ end
10
10
 
11
- def setup
12
- if @cfg.empty?
13
- Oxidized.asetus.user.output.file.directory = File.join(Config::Root, 'configs')
14
- Oxidized.asetus.save :user
15
- raise NoConfig, 'no output file config, edit ~/.config/oxidized/config'
11
+ def setup
12
+ if @cfg.empty?
13
+ Oxidized.asetus.user.output.file.directory = File.join(Config::Root, 'configs')
14
+ Oxidized.asetus.save :user
15
+ raise NoConfig, 'no output file config, edit ~/.config/oxidized/config'
16
+ end
16
17
  end
17
- end
18
18
 
19
- def store node, outputs, opt={}
20
- file = File.expand_path @cfg.directory
21
- if opt[:group]
22
- file = File.join File.dirname(file), opt[:group]
19
+ def store node, outputs, opt = {}
20
+ file = File.expand_path @cfg.directory
21
+ if opt[:group]
22
+ file = File.join File.dirname(file), opt[:group]
23
+ end
24
+ FileUtils.mkdir_p file
25
+ file = File.join file, node
26
+ open(file, 'w') { |fh| fh.write outputs.to_cfg }
27
+ @commitref = file
23
28
  end
24
- FileUtils.mkdir_p file
25
- file = File.join file, node
26
- open(file, 'w') { |fh| fh.write outputs.to_cfg }
27
- @commitref = file
28
- end
29
29
 
30
- def fetch node, group
31
- cfg_dir = File.expand_path @cfg.directory
32
- node_name = node.name
30
+ def fetch node, group
31
+ cfg_dir = File.expand_path @cfg.directory
32
+ node_name = node.name
33
33
 
34
- if group # group is explicitly defined by user
35
- cfg_dir = File.join File.dirname(cfg_dir), group
36
- File.read File.join(cfg_dir, node_name)
37
- else
38
- if File.exists? File.join(cfg_dir, node_name) # node configuration file is stored on base directory
34
+ if group # group is explicitly defined by user
35
+ cfg_dir = File.join File.dirname(cfg_dir), group
39
36
  File.read File.join(cfg_dir, node_name)
40
37
  else
41
- path = Dir.glob(File.join(File.dirname(cfg_dir), '**', node_name)).first # fetch node in all groups
42
- File.read path
38
+ if File.exists? 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
43
44
  end
45
+ rescue Errno::ENOENT
46
+ return nil
44
47
  end
45
- rescue Errno::ENOENT
46
- return nil
47
- end
48
48
 
49
- def version node, group
50
- # not supported
51
- []
52
- end
49
+ def version node, group
50
+ # not supported
51
+ []
52
+ end
53
53
 
54
- def get_version node, group, oid
55
- 'not supported'
54
+ def get_version node, group, oid
55
+ 'not supported'
56
+ end
56
57
  end
57
-
58
- end
59
58
  end
@@ -1,74 +1,73 @@
1
1
  module Oxidized
2
- class Git < Output
3
- class GitError < OxidizedError; end
4
- begin
5
- require 'rugged'
6
- rescue LoadError
7
- raise OxidizedError, 'rugged not found: sudo gem install rugged'
8
- end
9
-
10
- attr_reader :commitref
2
+ class Git < Output
3
+ class GitError < OxidizedError; end
4
+ begin
5
+ require 'rugged'
6
+ rescue LoadError
7
+ raise OxidizedError, 'rugged not found: sudo gem install rugged'
8
+ end
11
9
 
12
- def initialize
13
- @cfg = Oxidized.config.output.git
14
- end
10
+ attr_reader :commitref
15
11
 
16
- def setup
17
- if @cfg.empty?
18
- Oxidized.asetus.user.output.git.user = 'Oxidized'
19
- Oxidized.asetus.user.output.git.email = 'o@example.com'
20
- Oxidized.asetus.user.output.git.repo = File.join(Config::Root, 'oxidized.git')
21
- Oxidized.asetus.save :user
22
- raise NoConfig, 'no output git config, edit ~/.config/oxidized/config'
12
+ def initialize
13
+ @cfg = Oxidized.config.output.git
23
14
  end
24
15
 
25
- if @cfg.repo.respond_to?(:each)
26
- @cfg.repo.each do |group, repo|
27
- @cfg.repo["#{group}="] = File.expand_path repo
16
+ def setup
17
+ if @cfg.empty?
18
+ Oxidized.asetus.user.output.git.user = 'Oxidized'
19
+ Oxidized.asetus.user.output.git.email = 'o@example.com'
20
+ Oxidized.asetus.user.output.git.repo = File.join(Config::Root, 'oxidized.git')
21
+ Oxidized.asetus.save :user
22
+ raise NoConfig, 'no output git config, edit ~/.config/oxidized/config'
28
23
  end
29
- else
30
- @cfg.repo = File.expand_path @cfg.repo
31
- end
32
- end
33
24
 
34
- def store file, outputs, opt={}
35
- @msg = opt[:msg]
36
- @user = (opt[:user] or @cfg.user)
37
- @email = (opt[:email] or @cfg.email)
38
- @opt = opt
39
- @commitref = nil
40
- repo = @cfg.repo
41
-
42
- outputs.types.each do |type|
43
- type_cfg = ''
44
- type_repo = File.join(File.dirname(repo), type + '.git')
45
- outputs.type(type).each do |output|
46
- (type_cfg << output; next) if not output.name
47
- type_file = file + '--' + output.name
48
- if @cfg.type_as_directory?
49
- type_file = type + '/' + type_file
50
- type_repo = repo
25
+ if @cfg.repo.respond_to?(:each)
26
+ @cfg.repo.each do |group, repo|
27
+ @cfg.repo["#{group}="] = File.expand_path repo
51
28
  end
52
- update type_repo, type_file, output
29
+ else
30
+ @cfg.repo = File.expand_path @cfg.repo
53
31
  end
54
- update type_repo, file, type_cfg
55
32
  end
56
33
 
57
- update repo, file, outputs.to_cfg
58
- end
34
+ def store file, outputs, opt = {}
35
+ @msg = opt[:msg]
36
+ @user = (opt[:user] or @cfg.user)
37
+ @email = (opt[:email] or @cfg.email)
38
+ @opt = opt
39
+ @commitref = nil
40
+ repo = @cfg.repo
41
+
42
+ outputs.types.each do |type|
43
+ type_cfg = ''
44
+ type_repo = File.join(File.dirname(repo), type + '.git')
45
+ outputs.type(type).each do |output|
46
+ (type_cfg << output; next) if not output.name
47
+ type_file = file + '--' + output.name
48
+ if @cfg.type_as_directory?
49
+ type_file = type + '/' + type_file
50
+ type_repo = repo
51
+ end
52
+ update type_repo, type_file, output
53
+ end
54
+ update type_repo, file, type_cfg
55
+ end
59
56
 
57
+ update repo, file, outputs.to_cfg
58
+ end
60
59
 
61
- def fetch node, group
62
- begin
63
- repo, path = yield_repo_and_path(node, group)
64
- repo = Rugged::Repository.new repo
65
- index = repo.index
66
- index.read_tree repo.head.target.tree unless repo.empty?
67
- repo.read(index.get(path)[:oid]).data
68
- rescue
69
- 'node not found'
60
+ def fetch node, group
61
+ begin
62
+ repo, path = yield_repo_and_path(node, group)
63
+ repo = Rugged::Repository.new repo
64
+ index = repo.index
65
+ index.read_tree repo.head.target.tree unless repo.empty?
66
+ repo.read(index.get(path)[:oid]).data
67
+ rescue
68
+ 'node not found'
69
+ end
70
70
  end
71
- end
72
71
 
73
72
  # give a hash of all oid revision for the given node, and the date of the commit
74
73
  def version node, group
@@ -80,7 +79,7 @@ class Git < Output
80
79
  walker.sorting(Rugged::SORT_DATE)
81
80
  walker.push(repo.head.target)
82
81
  i = -1
83
- tab = []
82
+ tab = []
84
83
  walker.each do |commit|
85
84
  if commit.diff(paths: [path]).size > 0
86
85
  hash = {}
@@ -98,18 +97,18 @@ class Git < Output
98
97
  end
99
98
  end
100
99
 
101
- #give the blob of a specific revision
100
+ # give the blob of a specific revision
102
101
  def get_version node, group, oid
103
102
  begin
104
103
  repo, path = yield_repo_and_path(node, group)
105
104
  repo = Rugged::Repository.new repo
106
- repo.blob_at(oid,path).content
105
+ repo.blob_at(oid, path).content
107
106
  rescue
108
107
  'version not found'
109
108
  end
110
109
  end
111
110
 
112
- #give a hash with the patch of a diff between 2 revision and the stats (added and deleted lines)
111
+ # give a hash with the patch of a diff between 2 revision and the stats (added and deleted lines)
113
112
  def get_diff node, group, oid1, oid2
114
113
  begin
115
114
  diff_commits = nil
@@ -122,15 +121,15 @@ class Git < Output
122
121
  diff = repo.diff(commit_old, commit)
123
122
  diff.each do |patch|
124
123
  if /#{node.name}\s+/.match(patch.to_s.lines.first)
125
- diff_commits = {:patch => patch.to_s, :stat => patch.stat}
124
+ diff_commits = { :patch => patch.to_s, :stat => patch.stat }
126
125
  break
127
126
  end
128
127
  end
129
128
  else
130
129
  stat = commit.parents[0].diff(commit).stat
131
- stat = [stat[1],stat[2]]
130
+ stat = [stat[1], stat[2]]
132
131
  patch = commit.parents[0].diff(commit).patch
133
- diff_commits = {:patch => patch, :stat => stat}
132
+ diff_commits = { :patch => patch, :stat => stat }
134
133
  end
135
134
 
136
135
  diff_commits
@@ -139,68 +138,67 @@ class Git < Output
139
138
  end
140
139
  end
141
140
 
142
- private
141
+ private
143
142
 
144
- def yield_repo_and_path(node, group)
145
- repo, path = node.repo, node.name
143
+ def yield_repo_and_path(node, group)
144
+ repo, path = node.repo, node.name
146
145
 
147
- if group and @cfg.single_repo?
148
- path = "#{group}/#{node.name}"
149
- end
146
+ if group and @cfg.single_repo?
147
+ path = "#{group}/#{node.name}"
148
+ end
150
149
 
151
- [repo, path]
152
- end
150
+ [repo, path]
151
+ end
153
152
 
154
- def update repo, file, data
155
- return if data.empty?
153
+ def update repo, file, data
154
+ return if data.empty?
156
155
 
157
- if @opt[:group]
158
- if @cfg.single_repo?
159
- file = File.join @opt[:group], file
160
- else
161
- repo = if repo.is_a?(::String)
162
- File.join File.dirname(repo), @opt[:group] + '.git'
163
- else
164
- repo[@opt[:group]]
165
- end
156
+ if @opt[:group]
157
+ if @cfg.single_repo?
158
+ file = File.join @opt[:group], file
159
+ else
160
+ repo = if repo.is_a?(::String)
161
+ File.join File.dirname(repo), @opt[:group] + '.git'
162
+ else
163
+ repo[@opt[:group]]
164
+ end
165
+ end
166
166
  end
167
- end
168
167
 
169
- begin
170
- repo = Rugged::Repository.new repo
171
- update_repo repo, file, data, @msg, @user, @email
172
- rescue Rugged::OSError, Rugged::RepositoryError => open_error
173
168
  begin
174
- Rugged::Repository.init_at repo, :bare
175
- rescue => create_error
176
- raise GitError, "first '#{open_error.message}' was raised while opening git repo, then '#{create_error.message}' was while trying to create git repo"
169
+ repo = Rugged::Repository.new repo
170
+ update_repo repo, file, data, @msg, @user, @email
171
+ rescue Rugged::OSError, Rugged::RepositoryError => open_error
172
+ begin
173
+ Rugged::Repository.init_at repo, :bare
174
+ rescue => create_error
175
+ raise GitError, "first '#{open_error.message}' was raised while opening git repo, then '#{create_error.message}' was while trying to create git repo"
176
+ end
177
+ retry
177
178
  end
178
- retry
179
179
  end
180
- end
181
180
 
182
- def update_repo repo, file, data, msg, user, email
183
- oid = repo.write data, :blob
184
- index = repo.index
185
- index.read_tree repo.head.target.tree unless repo.empty?
186
-
187
- tree_old = index.write_tree repo
188
- index.add :path=>file, :oid=>oid, :mode=>0100644
189
- tree_new = index.write_tree repo
190
-
191
- if tree_old != tree_new
192
- repo.config['user.name'] = user
193
- repo.config['user.email'] = email
194
- @commitref = Rugged::Commit.create(repo,
195
- :tree => index.write_tree(repo),
196
- :message => msg,
197
- :parents => repo.empty? ? [] : [repo.head.target].compact,
198
- :update_ref => 'HEAD',
199
- )
200
-
201
- index.write
202
- true
181
+ def update_repo repo, file, data, msg, user, email
182
+ oid = repo.write data, :blob
183
+ index = repo.index
184
+ index.read_tree repo.head.target.tree unless repo.empty?
185
+
186
+ tree_old = index.write_tree repo
187
+ index.add :path => file, :oid => oid, :mode => 0100644
188
+ tree_new = index.write_tree repo
189
+
190
+ if tree_old != tree_new
191
+ repo.config['user.name'] = user
192
+ repo.config['user.email'] = email
193
+ @commitref = Rugged::Commit.create(repo,
194
+ :tree => index.write_tree(repo),
195
+ :message => msg,
196
+ :parents => repo.empty? ? [] : [repo.head.target].compact,
197
+ :update_ref => 'HEAD',)
198
+
199
+ index.write
200
+ true
201
+ end
203
202
  end
204
203
  end
205
204
  end
206
- end
@@ -1,244 +1,243 @@
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 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
+ def fetch node, group
90
+ begin
91
+ repo, path = yield_repo_and_path(node, group)
92
+ repo = Git.open repo
93
+ unlock repo
94
+ index = repo.index
95
+ # Empty repo ?
96
+ empty = File.exists? index.path
97
+ if empty
98
+ raise 'Empty git repo'
99
+ else
100
+ File.read path
101
+ end
102
+ lock repo
103
+ rescue
104
+ 'node not found'
105
+ end
106
+ end
107
+
108
+ # give a hash of all oid revision for the given node, and the date of the commit
109
+ def version node, group
110
+ begin
111
+ repo, path = yield_repo_and_path(node, group)
112
+
113
+ repo = Git.open repo
114
+ unlock repo
115
+ walker = repo.log.path(path)
116
+ i = -1
117
+ tab = []
118
+ walker.each do |commit|
119
+ hash = {}
120
+ hash[:date] = commit.date.to_s
121
+ hash[:oid] = commit.objectish
122
+ hash[:author] = commit.author
123
+ hash[:message] = commit.message
124
+ tab[i += 1] = hash
125
+ end
126
+ walker.reset
127
+ tab
128
+ rescue
129
+ 'node not found'
130
+ end
131
+ end
132
+
133
+ # give the blob of a specific revision
134
+ def get_version node, group, oid
135
+ begin
136
+ repo, path = yield_repo_and_path(node, group)
137
+ repo = Git.open repo
138
+ unlock repo
139
+ repo.gtree(oid).files[path].contents
140
+ rescue
141
+ 'version not found'
142
+ ensure
143
+ lock repo
144
+ end
145
+ end
146
+
147
+ # give a hash with the patch of a diff between 2 revision and the stats (added and deleted lines)
148
+ def get_diff node, group, oid1, oid2
149
+ begin
150
+ diff_commits = nil
151
+ repo, path = yield_repo_and_path(node, group)
152
+ repo = Git.open repo
153
+ unlock repo
154
+ commit = repo.gcommit(oid1)
155
+
156
+ if oid2
157
+ commit_old = repo.gcommit(oid2)
158
+ diff = repo.diff(commit_old, commit)
159
+ stats = [diff.stats[:files][node.name][:insertions], diff.stats[:files][node.name][:deletions]]
160
+ diff.each do |patch|
161
+ if /#{node.name}\s+/.match(patch.patch.to_s.lines.first)
162
+ diff_commits = { :patch => patch.patch.to_s, :stat => stats }
163
+ break
164
+ end
165
+ end
166
+ else
167
+ stat = commit.parents[0].diff(commit).stats
168
+ stat = [stat[:files][node.name][:insertions], stat[:files][node.name][:deletions]]
169
+ patch = commit.parents[0].diff(commit).patch
170
+ diff_commits = { :patch => patch, :stat => stat }
171
+ end
172
+ lock repo
173
+ diff_commits
174
+ rescue
175
+ 'no diffs'
176
+ ensure
177
+ lock repo
178
+ end
179
+ end
180
+
181
+ private
182
+
183
+ def yield_repo_and_path(node, group)
184
+ repo, path = node.repo, node.name
185
+
186
+ if group and @cfg.single_repo?
187
+ path = "#{group}/#{node.name}"
188
+ end
189
+
190
+ [repo, path]
191
+ end
192
+
193
+ def update repo, file, data
194
+ return if data.empty?
195
+
196
+ if @opt[:group]
197
+ if @cfg.single_repo?
198
+ file = File.join @opt[:group], file
199
+ else
200
+ repo = if repo.is_a?(::String)
201
+ File.join File.dirname(repo), @opt[:group] + '.git'
202
+ else
203
+ repo[@opt[:group]]
204
+ end
205
+ end
206
+ end
207
+
208
+ begin
209
+ update_repo repo, file, data, @msg, @user, @email
210
+ rescue Git::GitExecuteError, ArgumentError => open_error
211
+ Oxidized.logger.debug "open_error #{open_error} #{file}"
212
+ begin
213
+ grepo = Git.init repo
214
+ crypt_init grepo
215
+ rescue => create_error
216
+ raise GitCryptError, "first '#{open_error.message}' was raised while opening git repo, then '#{create_error.message}' was while trying to create git repo"
217
+ end
218
+ retry
219
+ end
220
+ end
221
+
222
+ def update_repo repo, file, data, msg, user, email
223
+ grepo = Git.open repo
224
+ grepo.config('user.name', user)
225
+ grepo.config('user.email', email)
226
+ grepo.chdir do
227
+ unlock grepo
228
+ File.write(file, data)
229
+ grepo.add(file)
230
+ if grepo.status[file].nil?
231
+ grepo.commit(msg)
232
+ @commitref = grepo.log(1).first.objectish
233
+ true
234
+ elsif !grepo.status[file].type.nil?
235
+ grepo.commit(msg)
236
+ @commitref = grepo.log(1).first.objectish
237
+ true
238
+ end
239
+ lock grepo
240
+ end
241
+ end
242
+ end
244
243
  end