oxidized 0.30.1 → 0.31.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +2 -2
  3. data/.github/workflows/stale.yml +4 -2
  4. data/.rubocop.yml +18 -2
  5. data/.rubocop_todo.yml +5 -12
  6. data/CHANGELOG.md +61 -1
  7. data/CONTRIBUTING.md +5 -0
  8. data/Dockerfile +82 -21
  9. data/README.md +5 -21
  10. data/Rakefile +3 -2
  11. data/docs/Configuration.md +36 -12
  12. data/docs/Creating-Models.md +45 -4
  13. data/docs/Hooks.md +34 -0
  14. data/docs/Issues.md +91 -0
  15. data/docs/Model-Notes/Cumulus.md +5 -0
  16. data/docs/Model-Notes/FSOS.md +5 -0
  17. data/docs/Model-Notes/FortiOS.md +21 -5
  18. data/docs/Model-Notes/HPEAruba.md +31 -0
  19. data/docs/Model-Notes/OS6.md +10 -0
  20. data/docs/Model-Notes/RouterOS.md +15 -0
  21. data/docs/Model-Notes/SikluMHTG.md +7 -0
  22. data/docs/Outputs.md +2 -0
  23. data/docs/Release.md +18 -15
  24. data/docs/Sources.md +21 -0
  25. data/docs/Supported-OS-Types.md +11 -5
  26. data/docs/Troubleshooting.md +35 -0
  27. data/examples/device-simulation/README.md +173 -0
  28. data/examples/device-simulation/cmdsets/aoscx +9 -0
  29. data/examples/device-simulation/cmdsets/arubainstant +5 -0
  30. data/examples/device-simulation/cmdsets/asa +7 -0
  31. data/examples/device-simulation/cmdsets/ios +7 -0
  32. data/examples/device-simulation/cmdsets/nxos +5 -0
  33. data/examples/device-simulation/cmdsets/routeros +5 -0
  34. data/examples/device-simulation/cmdsets/srosmd +11 -0
  35. data/examples/device-simulation/device2yaml.rb +225 -0
  36. data/examples/device-simulation/yaml/aoscx_R0X25A-6410_FL.10.10.1100.yaml +2281 -0
  37. data/examples/device-simulation/yaml/aoscx_R8N85A-C6000-48G-CL4_PL.10.08.1010.yaml +451 -0
  38. data/examples/device-simulation/yaml/arubainstant_IAP515_8.10.0.6_VWLC.yaml +213 -0
  39. data/examples/device-simulation/yaml/asa_5512_9.12-4-67_single-context.yaml +531 -0
  40. data/examples/device-simulation/yaml/asr920_16.8.1b.yaml +1122 -0
  41. data/examples/device-simulation/yaml/garderos_R7709_003_006_068.yaml +101 -0
  42. data/examples/device-simulation/yaml/iosxe_C9200L-24P-4G_17.09.04a.yaml +514 -0
  43. data/examples/device-simulation/yaml/iosxe_C9800-L-F-K9_17.06.05.yaml +417 -0
  44. data/examples/device-simulation/yaml/riverbed_915.yaml +123 -0
  45. data/examples/device-simulation/yaml/routeros_CHR_7.10.1.yaml +145 -0
  46. data/examples/device-simulation/yaml/routeros_CHR_7.16.yaml +79 -0
  47. data/examples/device-simulation/yaml/routeros_L009UiGS_7.15.2.yaml +353 -0
  48. data/examples/podman-compose/Makefile +60 -17
  49. data/examples/podman-compose/README.md +63 -27
  50. data/examples/podman-compose/docker-compose.yml +11 -2
  51. data/examples/podman-compose/gitserver/.gitignore +1 -0
  52. data/examples/podman-compose/gitserver/Dockerfile +14 -0
  53. data/examples/podman-compose/model-simulation/Dockerfile-model +1 -1
  54. data/examples/podman-compose/model-simulation/asternos.sh +2 -0
  55. data/examples/podman-compose/oxidized-config/.gitignore +2 -0
  56. data/examples/podman-compose/oxidized-config/config +1 -1
  57. data/examples/podman-compose/oxidized-config/config_csv-file +46 -0
  58. data/examples/podman-compose/oxidized-config/config_csv-gitserver +56 -0
  59. data/examples/podman-compose/oxidized-ssh/.gitignore +1 -0
  60. data/lib/oxidized/config.rb +7 -1
  61. data/lib/oxidized/hook/githubrepo.rb +37 -7
  62. data/lib/oxidized/hook/slackdiff.rb +29 -7
  63. data/lib/oxidized/input/http.rb +1 -0
  64. data/lib/oxidized/input/telnet.rb +1 -1
  65. data/lib/oxidized/manager.rb +17 -16
  66. data/lib/oxidized/model/aoscx.rb +16 -2
  67. data/lib/oxidized/model/aosw.rb +7 -1
  68. data/lib/oxidized/model/arubainstant.rb +90 -0
  69. data/lib/oxidized/model/audiocodes.rb +2 -2
  70. data/lib/oxidized/model/cnos.rb +13 -10
  71. data/lib/oxidized/model/cumulus.rb +3 -0
  72. data/lib/oxidized/model/dlink.rb +1 -0
  73. data/lib/oxidized/model/dlinknextgen.rb +3 -0
  74. data/lib/oxidized/model/edgecos.rb +2 -1
  75. data/lib/oxidized/model/eos.rb +2 -0
  76. data/lib/oxidized/model/f5os.rb +17 -0
  77. data/lib/oxidized/model/firewareos.rb +10 -1
  78. data/lib/oxidized/model/fortios.rb +24 -1
  79. data/lib/oxidized/model/garderos.rb +43 -0
  80. data/lib/oxidized/model/h3c.rb +1 -1
  81. data/lib/oxidized/model/ibos.rb +1 -0
  82. data/lib/oxidized/model/ios.rb +20 -12
  83. data/lib/oxidized/model/iosxr.rb +1 -1
  84. data/lib/oxidized/model/lenovonos.rb +2 -0
  85. data/lib/oxidized/model/linuxgeneric.rb +1 -1
  86. data/lib/oxidized/model/netgear.rb +1 -1
  87. data/lib/oxidized/model/nodegrid.rb +1 -1
  88. data/lib/oxidized/model/nsxdfw.rb +30 -0
  89. data/lib/oxidized/model/nxos.rb +2 -1
  90. data/lib/oxidized/model/os6.rb +48 -0
  91. data/lib/oxidized/model/rgos.rb +1 -1
  92. data/lib/oxidized/model/riverbed.rb +104 -0
  93. data/lib/oxidized/model/routeros.rb +2 -2
  94. data/lib/oxidized/model/saos.rb +18 -1
  95. data/lib/oxidized/model/siklumhtg.rb +22 -0
  96. data/lib/oxidized/model/uplinkolt.rb +46 -0
  97. data/lib/oxidized/model/vyatta.rb +2 -2
  98. data/lib/oxidized/model/xos.rb +7 -0
  99. data/lib/oxidized/node.rb +30 -18
  100. data/lib/oxidized/nodes.rb +13 -5
  101. data/lib/oxidized/output/file.rb +45 -42
  102. data/lib/oxidized/output/git.rb +185 -160
  103. data/lib/oxidized/output/gitcrypt.rb +188 -186
  104. data/lib/oxidized/output/http.rb +53 -51
  105. data/lib/oxidized/output/output.rb +6 -4
  106. data/lib/oxidized/source/csv.rb +44 -49
  107. data/lib/oxidized/source/http.rb +63 -81
  108. data/lib/oxidized/source/jsonfile.rb +63 -0
  109. data/lib/oxidized/source/source.rb +43 -18
  110. data/lib/oxidized/source/sql.rb +66 -59
  111. data/lib/oxidized/version.rb +2 -2
  112. data/oxidized.gemspec +22 -16
  113. metadata +111 -15
@@ -1,227 +1,229 @@
1
1
  module Oxidized
2
- class GitCrypt < Output
3
- using Refinements
4
- class GitCryptError < OxidizedError; end
5
- begin
6
- require 'git'
7
- rescue LoadError
8
- raise OxidizedError, 'git not found: sudo gem install git'
9
- end
10
-
11
- attr_reader :commitref
2
+ module Output
3
+ class GitCrypt < Output
4
+ using Refinements
5
+ class GitCryptError < OxidizedError; end
6
+ begin
7
+ require 'git'
8
+ rescue LoadError
9
+ raise OxidizedError, 'git not found: sudo gem install git'
10
+ end
12
11
 
13
- def initialize
14
- super
15
- @cfg = Oxidized.config.output.gitcrypt
16
- @gitcrypt_cmd = "/usr/bin/git-crypt"
17
- @gitcrypt_init = @gitcrypt_cmd + " init"
18
- @gitcrypt_unlock = @gitcrypt_cmd + " unlock"
19
- @gitcrypt_lock = @gitcrypt_cmd + " lock"
20
- @gitcrypt_adduser = @gitcrypt_cmd + " add-gpg-user --trusted "
21
- end
12
+ attr_reader :commitref
22
13
 
23
- def setup
24
- if @cfg.empty?
25
- Oxidized.asetus.user.output.gitcrypt.user = 'Oxidized'
26
- Oxidized.asetus.user.output.gitcrypt.email = 'o@example.com'
27
- Oxidized.asetus.user.output.gitcrypt.repo = File.join(Config::ROOT, 'oxidized.git')
28
- Oxidized.asetus.save :user
29
- raise NoConfig, 'no output git config, edit ~/.config/oxidized/config'
14
+ def initialize
15
+ super
16
+ @cfg = Oxidized.config.output.gitcrypt
17
+ @gitcrypt_cmd = "/usr/bin/git-crypt"
18
+ @gitcrypt_init = @gitcrypt_cmd + " init"
19
+ @gitcrypt_unlock = @gitcrypt_cmd + " unlock"
20
+ @gitcrypt_lock = @gitcrypt_cmd + " lock"
21
+ @gitcrypt_adduser = @gitcrypt_cmd + " add-gpg-user --trusted "
30
22
  end
31
23
 
32
- if @cfg.repo.respond_to?(:each)
33
- @cfg.repo.each do |group, repo|
34
- @cfg.repo["#{group}="] = File.expand_path repo
24
+ def setup
25
+ if @cfg.empty?
26
+ Oxidized.asetus.user.output.gitcrypt.user = 'Oxidized'
27
+ Oxidized.asetus.user.output.gitcrypt.email = 'o@example.com'
28
+ Oxidized.asetus.user.output.gitcrypt.repo = File.join(Config::ROOT, 'oxidized.git')
29
+ Oxidized.asetus.save :user
30
+ raise NoConfig, "no output git config, edit #{Oxidized::Config.configfile}"
31
+ end
32
+
33
+ if @cfg.repo.respond_to?(:each)
34
+ @cfg.repo.each do |group, repo|
35
+ @cfg.repo["#{group}="] = File.expand_path repo
36
+ end
37
+ else
38
+ @cfg.repo = File.expand_path @cfg.repo
35
39
  end
36
- else
37
- @cfg.repo = File.expand_path @cfg.repo
38
40
  end
39
- end
40
41
 
41
- def crypt_init(repo)
42
- repo.chdir do
43
- system(@gitcrypt_init)
44
- @cfg.users.each do |user|
45
- system("#{@gitcrypt_adduser} #{user}")
42
+ def crypt_init(repo)
43
+ repo.chdir do
44
+ system(@gitcrypt_init)
45
+ @cfg.users.each do |user|
46
+ system("#{@gitcrypt_adduser} #{user}")
47
+ end
48
+ File.write(".gitattributes", "* filter=git-crypt diff=git-crypt\n.gitattributes !filter !diff")
49
+ repo.add(".gitattributes")
50
+ repo.commit("Initial commit: crypt all config files")
46
51
  end
47
- File.write(".gitattributes", "* filter=git-crypt diff=git-crypt\n.gitattributes !filter !diff")
48
- repo.add(".gitattributes")
49
- repo.commit("Initial commit: crypt all config files")
50
52
  end
51
- end
52
53
 
53
- def lock(repo)
54
- repo.chdir do
55
- system(@gitcrypt_lock)
54
+ def lock(repo)
55
+ repo.chdir do
56
+ system(@gitcrypt_lock)
57
+ end
56
58
  end
57
- end
58
59
 
59
- def unlock(repo)
60
- repo.chdir do
61
- system(@gitcrypt_unlock)
60
+ def unlock(repo)
61
+ repo.chdir do
62
+ system(@gitcrypt_unlock)
63
+ end
62
64
  end
63
- end
64
65
 
65
- def store(file, outputs, opt = {})
66
- @msg = opt[:msg]
67
- @user = opt[:user] || @cfg.user
68
- @email = opt[:email] || @cfg.email
69
- @opt = opt
70
- @commitref = nil
71
- repo = @cfg.repo
72
-
73
- outputs.types.each do |type|
74
- type_cfg = ''
75
- type_repo = File.join(File.dirname(repo), type + '.git')
76
- outputs.type(type).each do |output|
77
- (type_cfg << output; next) unless output.name # rubocop:disable Style/Semicolon
78
- type_file = file + '--' + output.name
79
- if @cfg.type_as_directory?
80
- type_file = type + '/' + type_file
81
- type_repo = repo
66
+ def store(file, outputs, opt = {})
67
+ @msg = opt[:msg]
68
+ @user = opt[:user] || @cfg.user
69
+ @email = opt[:email] || @cfg.email
70
+ @opt = opt
71
+ @commitref = nil
72
+ repo = @cfg.repo
73
+
74
+ outputs.types.each do |type|
75
+ type_cfg = ''
76
+ type_repo = File.join(File.dirname(repo), type + '.git')
77
+ outputs.type(type).each do |output|
78
+ (type_cfg << output; next) unless output.name # rubocop:disable Style/Semicolon
79
+ type_file = file + '--' + output.name
80
+ if @cfg.type_as_directory?
81
+ type_file = type + '/' + type_file
82
+ type_repo = repo
83
+ end
84
+ update type_repo, type_file, output
82
85
  end
83
- update type_repo, type_file, output
86
+ update type_repo, file, type_cfg
84
87
  end
85
- update type_repo, file, type_cfg
86
- end
87
88
 
88
- update repo, file, outputs.to_cfg
89
- end
89
+ update repo, file, outputs.to_cfg
90
+ end
90
91
 
91
- def fetch(node, group)
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
- raise 'Empty git repo' if File.exist?(index.path)
98
-
99
- File.read path
100
- lock repo
101
- rescue StandardError
102
- 'node not found'
103
- end
92
+ def fetch(node, group)
93
+ repo, path = yield_repo_and_path(node, group)
94
+ repo = Git.open repo
95
+ unlock repo
96
+ index = repo.index
97
+ # Empty repo ?
98
+ raise 'Empty git repo' if File.exist?(index.path)
99
+
100
+ File.read path
101
+ lock repo
102
+ rescue StandardError
103
+ 'node not found'
104
+ end
104
105
 
105
- # give a hash of all oid revision for the given node, and the date of the commit
106
- def version(node, group)
107
- repo, path = yield_repo_and_path(node, group)
108
-
109
- repo = Git.open repo
110
- unlock repo
111
- walker = repo.log.path(path)
112
- i = -1
113
- tab = []
114
- walker.each do |commit|
115
- hash = {}
116
- hash[:date] = commit.date.to_s
117
- hash[:oid] = commit.objectish
118
- hash[:author] = commit.author
119
- hash[:message] = commit.message
120
- tab[i += 1] = hash
106
+ # give a hash of all oid revision for the given node, and the date of the commit
107
+ def version(node, group)
108
+ repo, path = yield_repo_and_path(node, group)
109
+
110
+ repo = Git.open repo
111
+ unlock repo
112
+ walker = repo.log.path(path)
113
+ i = -1
114
+ tab = []
115
+ walker.each do |commit|
116
+ hash = {}
117
+ hash[:date] = commit.date.to_s
118
+ hash[:oid] = commit.objectish
119
+ hash[:author] = commit.author
120
+ hash[:message] = commit.message
121
+ tab[i += 1] = hash
122
+ end
123
+ walker.reset
124
+ tab
125
+ rescue StandardError
126
+ 'node not found'
121
127
  end
122
- walker.reset
123
- tab
124
- rescue StandardError
125
- 'node not found'
126
- end
127
128
 
128
- # give the blob of a specific revision
129
- def get_version(node, group, oid)
130
- repo, path = yield_repo_and_path(node, group)
131
- repo = Git.open repo
132
- unlock repo
133
- repo.gtree(oid).files[path].contents
134
- rescue StandardError
135
- 'version not found'
136
- ensure
137
- lock repo
138
- end
129
+ # give the blob of a specific revision
130
+ def get_version(node, group, oid)
131
+ repo, path = yield_repo_and_path(node, group)
132
+ repo = Git.open repo
133
+ unlock repo
134
+ repo.gtree(oid).files[path].contents
135
+ rescue StandardError
136
+ 'version not found'
137
+ ensure
138
+ lock repo
139
+ end
139
140
 
140
- # give a hash with the patch of a diff between 2 revision and the stats (added and deleted lines)
141
- def get_diff(node, group, oid1, oid2)
142
- diff_commits = nil
143
- repo, _path = yield_repo_and_path(node, group)
144
- repo = Git.open repo
145
- unlock repo
146
- commit = repo.gcommit(oid1)
147
-
148
- if oid2
149
- commit_old = repo.gcommit(oid2)
150
- diff = repo.diff(commit_old, commit)
151
- stats = [diff.stats[:files][node.name][:insertions], diff.stats[:files][node.name][:deletions]]
152
- diff.each do |patch|
153
- if /#{node.name}\s+/ =~ patch.patch.to_s.lines.first
154
- diff_commits = { patch: patch.patch.to_s, stat: stats }
155
- break
141
+ # give a hash with the patch of a diff between 2 revision and the stats (added and deleted lines)
142
+ def get_diff(node, group, oid1, oid2)
143
+ diff_commits = nil
144
+ repo, _path = yield_repo_and_path(node, group)
145
+ repo = Git.open repo
146
+ unlock repo
147
+ commit = repo.gcommit(oid1)
148
+
149
+ if oid2
150
+ commit_old = repo.gcommit(oid2)
151
+ diff = repo.diff(commit_old, commit)
152
+ stats = [diff.stats[:files][node.name][:insertions], diff.stats[:files][node.name][:deletions]]
153
+ diff.each do |patch|
154
+ if /#{node.name}\s+/ =~ patch.patch.to_s.lines.first
155
+ diff_commits = { patch: patch.patch.to_s, stat: stats }
156
+ break
157
+ end
156
158
  end
159
+ else
160
+ stat = commit.parents[0].diff(commit).stats
161
+ stat = [stat[:files][node.name][:insertions], stat[:files][node.name][:deletions]]
162
+ patch = commit.parents[0].diff(commit).patch
163
+ diff_commits = { patch: patch, stat: stat }
157
164
  end
158
- else
159
- stat = commit.parents[0].diff(commit).stats
160
- stat = [stat[:files][node.name][:insertions], stat[:files][node.name][:deletions]]
161
- patch = commit.parents[0].diff(commit).patch
162
- diff_commits = { patch: patch, stat: stat }
165
+ lock repo
166
+ diff_commits
167
+ rescue StandardError
168
+ 'no diffs'
169
+ ensure
170
+ lock repo
163
171
  end
164
- lock repo
165
- diff_commits
166
- rescue StandardError
167
- 'no diffs'
168
- ensure
169
- lock repo
170
- end
171
-
172
- private
173
172
 
174
- def yield_repo_and_path(node, group)
175
- repo, path = node.repo, node.name
173
+ private
176
174
 
177
- path = "#{group}/#{node.name}" if group && @cfg.single_repo?
175
+ def yield_repo_and_path(node, group)
176
+ repo, path = node.repo, node.name
178
177
 
179
- [repo, path]
180
- end
178
+ path = "#{group}/#{node.name}" if group && @cfg.single_repo?
181
179
 
182
- def update(repo, file, data)
183
- return if data.empty?
180
+ [repo, path]
181
+ end
184
182
 
185
- if @opt[:group]
186
- if @cfg.single_repo?
187
- file = File.join @opt[:group], file
188
- else
189
- repo = if repo.is_a?(::String)
190
- File.join File.dirname(repo), @opt[:group] + '.git'
191
- else
192
- repo[@opt[:group]]
193
- end
183
+ def update(repo, file, data)
184
+ return if data.empty?
185
+
186
+ if @opt[:group]
187
+ if @cfg.single_repo?
188
+ file = File.join @opt[:group], file
189
+ else
190
+ repo = if repo.is_a?(::String)
191
+ File.join File.dirname(repo), @opt[:group] + '.git'
192
+ else
193
+ repo[@opt[:group]]
194
+ end
195
+ end
194
196
  end
195
- end
196
197
 
197
- begin
198
- update_repo repo, file, data, @msg, @user, @email
199
- rescue Git::GitExecuteError, ArgumentError => e
200
- Oxidized.logger.debug "open_error #{e} #{file}"
201
198
  begin
202
- grepo = Git.init repo
203
- crypt_init grepo
204
- rescue StandardError => create_error
205
- raise GitCryptError, "first '#{e.message}' was raised while opening git repo, then '#{create_error.message}' was while trying to create git repo"
199
+ update_repo repo, file, data, @msg, @user, @email
200
+ rescue Git::GitExecuteError, ArgumentError => e
201
+ Oxidized.logger.debug "open_error #{e} #{file}"
202
+ begin
203
+ grepo = Git.init repo
204
+ crypt_init grepo
205
+ rescue StandardError => create_error
206
+ raise GitCryptError, "first '#{e.message}' was raised while opening git repo, then '#{create_error.message}' was while trying to create git repo"
207
+ end
208
+ retry
206
209
  end
207
- retry
208
210
  end
209
- end
210
211
 
211
- def update_repo(repo, file, data, msg, user, email)
212
- grepo = Git.open repo
213
- grepo.config('user.name', user)
214
- grepo.config('user.email', email)
215
- grepo.chdir do
216
- unlock grepo
217
- File.write(file, data)
218
- grepo.add(file)
219
- if grepo.status[file].nil? || !grepo.status[file].type.nil?
220
- grepo.commit(msg)
221
- @commitref = grepo.log(1).first.objectish
222
- true
212
+ def update_repo(repo, file, data, msg, user, email)
213
+ grepo = Git.open repo
214
+ grepo.config('user.name', user)
215
+ grepo.config('user.email', email)
216
+ grepo.chdir do
217
+ unlock grepo
218
+ File.write(file, data)
219
+ grepo.add(file)
220
+ if grepo.status[file].nil? || !grepo.status[file].type.nil?
221
+ grepo.commit(msg)
222
+ @commitref = grepo.log(1).first.objectish
223
+ true
224
+ end
225
+ lock grepo
223
226
  end
224
- lock grepo
225
227
  end
226
228
  end
227
229
  end
@@ -1,61 +1,63 @@
1
1
  module Oxidized
2
- class Http < Output
3
- attr_reader :commitref
2
+ module Output
3
+ class Http < Output
4
+ attr_reader :commitref
4
5
 
5
- def initialize
6
- super
7
- @cfg = Oxidized.config.output.http
8
- end
6
+ def initialize
7
+ super
8
+ @cfg = Oxidized.config.output.http
9
+ end
9
10
 
10
- def setup
11
- return unless @cfg.empty?
11
+ def setup
12
+ return unless @cfg.empty?
12
13
 
13
- CFGS.user.output.http.user = 'Oxidized'
14
- CFGS.user.output.http.pasword = 'secret'
15
- CFGS.user.output.http.url = 'http://localhost/web-api/oxidized'
16
- CFGS.save :user
17
- raise NoConfig, 'no output http config, edit ~/.config/oxidized/config'
18
- end
14
+ Oxidized.asetus.user.output.http.user = 'Oxidized'
15
+ Oxidized.asetus.user.output.http.pasword = 'secret'
16
+ Oxidized.asetus.user.output.http.url = 'http://localhost/web-api/oxidized'
17
+ Oxidized.asetus.save :user
18
+ raise NoConfig, "no output http config, edit #{Oxidized::Config.configfile}"
19
+ end
19
20
 
20
- require "net/http"
21
- require "uri"
22
- require "json"
23
-
24
- def store(node, outputs, opt = {})
25
- @commitref = nil
26
- uri = URI.parse @cfg.url
27
- http = Net::HTTP.new uri.host, uri.port
28
- # http.use_ssl = true if uri.scheme = 'https'
29
- req = Net::HTTP::Post.new(uri.request_uri, 'Content-Type' => 'application/json')
30
- req.basic_auth @cfg.user, @cfg.password
31
- req.body = generate_json(node, outputs, opt)
32
- response = http.request req
33
-
34
- case response.code.to_i
35
- when 200 || 201
36
- Oxidized.logger.info "Configuration http backup complete for #{node}"
37
- p [:success]
38
- when (400..499)
39
- Oxidized.logger.info "Configuration http backup for #{node} failed status: #{response.body}"
40
- p [:bad_request]
41
- when (500..599)
42
- p [:server_problems]
43
- Oxidized.logger.info "Configuration http backup for #{node} failed status: #{response.body}"
21
+ require "net/http"
22
+ require "uri"
23
+ require "json"
24
+
25
+ def store(node, outputs, opt = {})
26
+ @commitref = nil
27
+ uri = URI.parse @cfg.url
28
+ http = Net::HTTP.new uri.host, uri.port
29
+ # http.use_ssl = true if uri.scheme = 'https'
30
+ req = Net::HTTP::Post.new(uri.request_uri, 'Content-Type' => 'application/json')
31
+ req.basic_auth @cfg.user, @cfg.password
32
+ req.body = generate_json(node, outputs, opt)
33
+ response = http.request req
34
+
35
+ case response.code.to_i
36
+ when 200 || 201
37
+ Oxidized.logger.info "Configuration http backup complete for #{node}"
38
+ p [:success]
39
+ when (400..499)
40
+ Oxidized.logger.info "Configuration http backup for #{node} failed status: #{response.body}"
41
+ p [:bad_request]
42
+ when (500..599)
43
+ p [:server_problems]
44
+ Oxidized.logger.info "Configuration http backup for #{node} failed status: #{response.body}"
45
+ end
44
46
  end
45
- end
46
47
 
47
- private
48
-
49
- def generate_json(node, outputs, opt)
50
- JSON.pretty_generate(
51
- 'msg' => opt[:msg],
52
- 'user' => opt[:user],
53
- 'email' => opt[:email],
54
- 'group' => opt[:group],
55
- 'node' => node,
56
- 'config' => outputs.to_cfg
57
- # actually we need to also iterate outputs, for other types like in gitlab. But most people don't use 'type' functionality.
58
- )
48
+ private
49
+
50
+ def generate_json(node, outputs, opt)
51
+ JSON.pretty_generate(
52
+ 'msg' => opt[:msg],
53
+ 'user' => opt[:user],
54
+ 'email' => opt[:email],
55
+ 'group' => opt[:group],
56
+ 'node' => node,
57
+ 'config' => outputs.to_cfg
58
+ # actually we need to also iterate outputs, for other types like in gitlab. But most people don't use 'type' functionality.
59
+ )
60
+ end
59
61
  end
60
62
  end
61
63
  end
@@ -1,9 +1,11 @@
1
1
  module Oxidized
2
- class Output
3
- class NoConfig < OxidizedError; end
2
+ module Output
3
+ class Output
4
+ class NoConfig < OxidizedError; end
4
5
 
5
- def cfg_to_str(cfg)
6
- cfg.select { |h| h[:type] == 'cfg' }.map { |h| h[:data] }.join
6
+ def cfg_to_str(cfg)
7
+ cfg.select { |h| h[:type] == 'cfg' }.map { |h| h[:data] }.join
8
+ end
7
9
  end
8
10
  end
9
11
  end
@@ -1,60 +1,55 @@
1
1
  module Oxidized
2
- class CSV < Source
3
- def initialize
4
- @cfg = Oxidized.config.source.csv
5
- super
6
- end
7
-
8
- def setup
9
- if @cfg.empty?
10
- Oxidized.asetus.user.source.csv.file = File.join(Config::ROOT, 'router.db')
11
- Oxidized.asetus.user.source.csv.delimiter = /:/
12
- Oxidized.asetus.user.source.csv.map.name = 0
13
- Oxidized.asetus.user.source.csv.map.model = 1
14
- Oxidized.asetus.user.source.csv.gpg = false
15
- Oxidized.asetus.save :user
16
- raise NoConfig, 'no source csv config, edit ~/.config/oxidized/config'
2
+ module Source
3
+ class CSV < Source
4
+ def initialize
5
+ @cfg = Oxidized.config.source.csv
6
+ super
17
7
  end
18
- require 'gpgme' if @cfg.gpg?
19
- end
20
-
21
- def load(_node_want = nil)
22
- nodes = []
23
- open_file.each_line do |line|
24
- next if line =~ /^\s*#/
25
-
26
- data = line.chomp.split(@cfg.delimiter, -1)
27
- next if data.empty?
28
8
 
29
- # map node parameters
30
- keys = {}
31
- @cfg.map.each do |key, position|
32
- keys[key.to_sym] = node_var_interpolate data[position]
9
+ def setup
10
+ if @cfg.empty?
11
+ Oxidized.asetus.user.source.csv.file = File.join(Config::ROOT, 'router.db')
12
+ Oxidized.asetus.user.source.csv.delimiter = /:/
13
+ Oxidized.asetus.user.source.csv.map.name = 0
14
+ Oxidized.asetus.user.source.csv.map.model = 1
15
+ Oxidized.asetus.user.source.csv.gpg = false
16
+ Oxidized.asetus.save :user
17
+ raise NoConfig, "no source csv config, edit #{Oxidized::Config.configfile}"
33
18
  end
34
- keys[:model] = map_model keys[:model] if keys.has_key? :model
35
- keys[:group] = map_group keys[:group] if keys.has_key? :group
19
+ require 'gpgme' if @cfg.gpg?
36
20
 
37
- # map node specific vars
38
- vars = {}
39
- @cfg.vars_map.each do |key, position|
40
- vars[key.to_sym] = node_var_interpolate data[position]
41
- end
42
- keys[:vars] = vars unless vars.empty?
21
+ # map.name is mandatory
22
+ return if @cfg.map.has_key?('name')
43
23
 
44
- nodes << keys
24
+ raise InvalidConfig, "map/name is a mandatory source attribute, edit #{Oxidized::Config.configfile}"
45
25
  end
46
- nodes
47
- end
48
26
 
49
- private
50
-
51
- def open_file
52
- file = File.expand_path(@cfg.file)
53
- if @cfg.gpg?
54
- crypto = GPGME::Crypto.new password: @cfg.gpg_password
55
- crypto.decrypt(File.open(file)).to_s
56
- else
57
- File.open(file)
27
+ def load(_node_want = nil)
28
+ nodes = []
29
+ open_file.each_line do |line|
30
+ next if line =~ /^\s*#/
31
+
32
+ data = line.chomp.split(@cfg.delimiter, -1)
33
+ next if data.empty?
34
+
35
+ # map node parameters
36
+ keys = {}
37
+ @cfg.map.each do |key, position|
38
+ keys[key.to_sym] = node_var_interpolate data[position]
39
+ end
40
+ keys[:model] = map_model keys[:model] if keys.has_key? :model
41
+ keys[:group] = map_group keys[:group] if keys.has_key? :group
42
+
43
+ # map node specific vars
44
+ vars = {}
45
+ @cfg.vars_map.each do |key, position|
46
+ vars[key.to_sym] = node_var_interpolate data[position]
47
+ end
48
+ keys[:vars] = vars unless vars.empty?
49
+
50
+ nodes << keys
51
+ end
52
+ nodes
58
53
  end
59
54
  end
60
55
  end