oxidized 0.29.1 → 0.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.coderabbit.yaml +21 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +45 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
- data/.github/ISSUE_TEMPLATE/support-request.md +39 -0
- data/.github/workflows/codeql.yml +4 -4
- data/.github/workflows/publishdocker.yml +108 -13
- data/.github/workflows/ruby.yml +3 -12
- data/.github/workflows/stale.yml +6 -1
- data/.gitignore +2 -0
- data/.rubocop.yml +69 -13
- data/.rubocop_todo.yml +13 -143
- data/CHANGELOG.md +431 -4
- data/CONTRIBUTING.md +189 -0
- data/Dockerfile +89 -34
- data/README.md +59 -188
- data/Rakefile +58 -12
- data/bin/oxidized +2 -5
- data/docs/Configuration.md +382 -149
- data/docs/Creating-Models.md +262 -10
- data/docs/DeviceSimulation.md +196 -0
- data/docs/Docker.md +246 -0
- data/docs/Hooks.md +146 -51
- data/docs/Inputs.md +237 -0
- data/docs/Issues.md +123 -0
- data/docs/Model-Notes/APC.md +72 -0
- data/docs/Model-Notes/Cumulus.md +5 -0
- data/docs/Model-Notes/EatonNetwork.md +18 -0
- data/docs/Model-Notes/ExaLink.md +43 -0
- data/docs/Model-Notes/FSOS.md +17 -0
- data/docs/Model-Notes/Fortinet.md +75 -0
- data/docs/Model-Notes/GrandstreamHT8xx.md +8 -0
- data/docs/Model-Notes/HPEAruba.md +32 -0
- data/docs/Model-Notes/IvantiConnectSecure.md +59 -0
- data/docs/Model-Notes/OS6.md +10 -0
- data/docs/Model-Notes/README.md +1 -20
- data/docs/Model-Notes/RouterOS.md +28 -0
- data/docs/Model-Notes/SikluMHTG.md +7 -0
- data/docs/Model-Notes/TrueNAS.md +23 -0
- data/docs/Model-Notes/XGS4600-Zyxel.md +5 -0
- data/docs/ModelUnitTests.md +219 -0
- data/docs/Outputs.md +102 -5
- data/docs/Release.md +102 -0
- data/docs/Ruby-API.md +135 -2
- data/docs/Sources.md +34 -0
- data/docs/Supported-OS-Types.md +207 -270
- data/docs/Troubleshooting.md +43 -1
- data/extra/device2yaml.rb +259 -0
- data/extra/gitdiff-msteams.sh +32 -5
- data/extra/hooks/modelrules.rb +55 -0
- data/extra/hooks/modelrulesadvanced.rb +167 -0
- data/extra/hooks/srcipmap.rb +54 -0
- data/extra/nagios_check_failing_nodes.rb +1 -1
- data/extra/oxidized.runit +1 -1
- data/extra/rest_client.rb +5 -4
- data/extra/syslog.rb +11 -6
- data/lib/oxidized/cli/support.rb +152 -0
- data/lib/oxidized/cli.rb +21 -6
- data/lib/oxidized/config/vars.rb +33 -14
- data/lib/oxidized/config.rb +28 -17
- data/lib/oxidized/core.rb +50 -8
- data/lib/oxidized/hook/ciscosparkdiff.rb +11 -9
- data/lib/oxidized/hook/exec.rb +5 -4
- data/lib/oxidized/hook/githubrepo.rb +55 -18
- data/lib/oxidized/hook/noophook.rb +2 -2
- data/lib/oxidized/hook/slackdiff.rb +50 -14
- data/lib/oxidized/hook/xmppdiff.rb +9 -9
- data/lib/oxidized/hook.rb +68 -16
- data/lib/oxidized/input/cli.rb +8 -3
- data/lib/oxidized/input/debugtext.rb +40 -0
- data/lib/oxidized/input/debugyaml.rb +82 -0
- data/lib/oxidized/input/exec.rb +2 -11
- data/lib/oxidized/input/ftp.rb +2 -19
- data/lib/oxidized/input/http.rb +67 -17
- data/lib/oxidized/input/input.rb +35 -14
- data/lib/oxidized/input/scp.rb +27 -0
- data/lib/oxidized/input/ssh.rb +59 -83
- data/lib/oxidized/input/sshbase.rb +102 -0
- data/lib/oxidized/input/telnet.rb +20 -19
- data/lib/oxidized/input/tftp.rb +8 -8
- data/lib/oxidized/job.rb +18 -7
- data/lib/oxidized/jobs.rb +11 -1
- data/lib/oxidized/logger.rb +51 -0
- data/lib/oxidized/manager.rb +18 -17
- data/lib/oxidized/model/acos.rb +2 -1
- data/lib/oxidized/model/addpack.rb +26 -0
- data/lib/oxidized/model/adtran.rb +5 -1
- data/lib/oxidized/model/adva.rb +3 -3
- data/lib/oxidized/model/airfiber.rb +1 -1
- data/lib/oxidized/model/aos7.rb +11 -0
- data/lib/oxidized/model/aoscx.rb +37 -29
- data/lib/oxidized/model/aosw.rb +39 -29
- data/lib/oxidized/model/apc_aos.rb +7 -2
- data/lib/oxidized/model/apcaos.rb +39 -0
- data/lib/oxidized/model/aricentiss.rb +9 -2
- data/lib/oxidized/model/arubainstant.rb +93 -0
- data/lib/oxidized/model/asa.rb +11 -10
- data/lib/oxidized/model/asternos.rb +22 -0
- data/lib/oxidized/model/asyncos.rb +3 -3
- data/lib/oxidized/model/audiocodes.rb +2 -2
- data/lib/oxidized/model/awplus.rb +15 -12
- data/lib/oxidized/model/axos.rb +1 -1
- data/lib/oxidized/model/bdcom.rb +1 -0
- data/lib/oxidized/model/c4cmts.rb +1 -2
- data/lib/oxidized/model/ciscosma.rb +1 -1
- data/lib/oxidized/model/ciscosmb.rb +6 -1
- data/lib/oxidized/model/cnos.rb +13 -10
- data/lib/oxidized/model/comtrol.rb +1 -1
- data/lib/oxidized/model/comware.rb +5 -3
- data/lib/oxidized/model/cumulus.rb +14 -2
- data/lib/oxidized/model/defacto.rb +26 -0
- data/lib/oxidized/model/dellx.rb +1 -1
- data/lib/oxidized/model/dlink.rb +5 -2
- data/lib/oxidized/model/dlinknextgen.rb +55 -0
- data/lib/oxidized/model/dnos.rb +3 -0
- data/lib/oxidized/model/dslcommands.rb +93 -0
- data/lib/oxidized/model/dslsetup.rb +102 -0
- data/lib/oxidized/model/eatonnetwork.rb +70 -0
- data/lib/oxidized/model/edgecos.rb +3 -1
- data/lib/oxidized/model/edgeos.rb +7 -6
- data/lib/oxidized/model/edgeswitch.rb +3 -1
- data/lib/oxidized/model/efos.rb +41 -0
- data/lib/oxidized/model/eltex.rb +4 -2
- data/lib/oxidized/model/enterasys800.rb +2 -2
- data/lib/oxidized/model/enterprise_sonic.rb +46 -0
- data/lib/oxidized/model/eos.rb +3 -1
- data/lib/oxidized/model/exalink.rb +36 -0
- data/lib/oxidized/model/f5os.rb +17 -0
- data/lib/oxidized/model/fabricos.rb +2 -2
- data/lib/oxidized/model/fastiron.rb +5 -3
- data/lib/oxidized/model/firebrick.rb +2 -2
- data/lib/oxidized/model/firelinuxos.rb +13 -6
- data/lib/oxidized/model/firewareos.rb +10 -1
- data/lib/oxidized/model/fortigate.rb +160 -0
- data/lib/oxidized/model/fortios.rb +38 -48
- data/lib/oxidized/model/fsos.rb +46 -0
- data/lib/oxidized/model/gaiaos.rb +4 -4
- data/lib/oxidized/model/garderos.rb +38 -0
- data/lib/oxidized/model/grandstreamht8xx.rb +19 -0
- data/lib/oxidized/model/h3c.rb +1 -1
- data/lib/oxidized/model/ibos.rb +1 -0
- data/lib/oxidized/model/ingate.rb +47 -0
- data/lib/oxidized/model/ios.rb +57 -30
- data/lib/oxidized/model/iosxr.rb +2 -2
- data/lib/oxidized/model/ironware.rb +7 -5
- data/lib/oxidized/model/ivanti.rb +54 -0
- data/lib/oxidized/model/junos.rb +12 -5
- data/lib/oxidized/model/kornfeldos.rb +33 -0
- data/lib/oxidized/model/lenovonos.rb +2 -0
- data/lib/oxidized/model/linksyssrw.rb +3 -3
- data/lib/oxidized/model/linuxgeneric.rb +4 -2
- data/lib/oxidized/model/macros.rb +60 -0
- data/lib/oxidized/model/mimosab11.rb +34 -0
- data/lib/oxidized/model/ml66.rb +33 -0
- data/lib/oxidized/model/mlnxos.rb +18 -14
- data/lib/oxidized/model/model.rb +98 -103
- data/lib/oxidized/model/mtrlrfs.rb +1 -0
- data/lib/oxidized/model/ndms.rb +6 -0
- data/lib/oxidized/model/netgear.rb +14 -3
- data/lib/oxidized/model/netonix.rb +1 -1
- data/lib/oxidized/model/netscaler.rb +1 -1
- data/lib/oxidized/model/nodegrid.rb +1 -1
- data/lib/oxidized/model/nsxdfw.rb +31 -0
- data/lib/oxidized/model/nsxfirewall.rb +2 -1
- data/lib/oxidized/model/nxos.rb +20 -15
- data/lib/oxidized/model/ocnos.rb +42 -0
- data/lib/oxidized/model/onefinity.rb +18 -0
- data/lib/oxidized/model/openbsd.rb +1 -1
- data/lib/oxidized/model/opengear.rb +36 -1
- data/lib/oxidized/model/openwrt.rb +6 -6
- data/lib/oxidized/model/opnsense.rb +9 -1
- data/lib/oxidized/model/os6.rb +48 -0
- data/lib/oxidized/model/outputs.rb +5 -0
- data/lib/oxidized/model/panos.rb +2 -0
- data/lib/oxidized/model/perle.rb +41 -0
- data/lib/oxidized/model/pfsense.rb +9 -0
- data/lib/oxidized/model/powerconnect.rb +32 -11
- data/lib/oxidized/model/procurve.rb +6 -2
- data/lib/oxidized/model/qtech.rb +3 -1
- data/lib/oxidized/model/quantaos.rb +8 -6
- data/lib/oxidized/model/rgos.rb +33 -0
- data/lib/oxidized/model/riverbed.rb +104 -0
- data/lib/oxidized/model/routeros.rb +18 -11
- data/lib/oxidized/model/saos.rb +18 -1
- data/lib/oxidized/model/saos10.rb +38 -0
- data/lib/oxidized/model/siklu.rb +1 -1
- data/lib/oxidized/model/siklumhtg.rb +22 -0
- data/lib/oxidized/model/sixwind.rb +28 -0
- data/lib/oxidized/model/slxos.rb +3 -3
- data/lib/oxidized/model/smartbyte.rb +48 -0
- data/lib/oxidized/model/sonicos.rb +27 -20
- data/lib/oxidized/model/speedtouch.rb +1 -1
- data/lib/oxidized/model/sros.rb +3 -3
- data/lib/oxidized/model/srosmd.rb +1 -1
- data/lib/oxidized/model/supermicro.rb +1 -1
- data/lib/oxidized/model/telco.rb +1 -1
- data/lib/oxidized/model/tmos.rb +1 -0
- data/lib/oxidized/model/tnsr.rb +57 -0
- data/lib/oxidized/model/tplink.rb +5 -5
- data/lib/oxidized/model/trango.rb +4 -2
- data/lib/oxidized/model/truenas.rb +64 -3
- data/lib/oxidized/model/ucs.rb +1 -1
- data/lib/oxidized/model/unifiap.rb +144 -0
- data/lib/oxidized/model/uplinkolt.rb +46 -0
- data/lib/oxidized/model/voltaire.rb +1 -1
- data/lib/oxidized/model/voss.rb +3 -0
- data/lib/oxidized/model/vrp.rb +5 -1
- data/lib/oxidized/model/vyatta.rb +9 -3
- data/lib/oxidized/model/vyos.rb +37 -0
- data/lib/oxidized/model/xos.rb +10 -1
- data/lib/oxidized/model/zhoneolt.rb +4 -2
- data/lib/oxidized/model/zynos.rb +67 -3
- data/lib/oxidized/model/zynosadsl.rb +14 -0
- data/lib/oxidized/model/zynoscli.rb +1 -1
- data/lib/oxidized/model/zynosgs.rb +2 -0
- data/lib/oxidized/model/zynosmgs.rb +32 -0
- data/lib/oxidized/node.rb +99 -64
- data/lib/oxidized/nodes.rb +40 -19
- data/lib/oxidized/output/file.rb +80 -43
- data/lib/oxidized/output/git.rb +295 -151
- data/lib/oxidized/output/gitcrypt.rb +193 -185
- data/lib/oxidized/output/http.rb +63 -51
- data/lib/oxidized/output/output.rb +20 -4
- data/lib/oxidized/signals.rb +44 -0
- data/lib/oxidized/source/csv.rb +49 -49
- data/lib/oxidized/source/http.rb +76 -63
- data/lib/oxidized/source/jsonfile.rb +68 -0
- data/lib/oxidized/source/source.rb +73 -18
- data/lib/oxidized/source/sql.rb +71 -59
- data/lib/oxidized/version.rb +6 -4
- data/lib/oxidized/worker.rb +57 -29
- data/lib/oxidized.rb +4 -24
- data/lib/refinements.rb +21 -1
- data/oxidized.gemspec +45 -21
- metadata +248 -41
- data/lib/oxidized/model/timos.rb +0 -10
|
@@ -1,226 +1,234 @@
|
|
|
1
1
|
module Oxidized
|
|
2
|
-
|
|
3
|
-
class
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
super
|
|
14
|
-
@cfg = Oxidized.config.output.gitcrypt
|
|
15
|
-
@gitcrypt_cmd = "/usr/bin/git-crypt"
|
|
16
|
-
@gitcrypt_init = @gitcrypt_cmd + " init"
|
|
17
|
-
@gitcrypt_unlock = @gitcrypt_cmd + " unlock"
|
|
18
|
-
@gitcrypt_lock = @gitcrypt_cmd + " lock"
|
|
19
|
-
@gitcrypt_adduser = @gitcrypt_cmd + " add-gpg-user --trusted "
|
|
20
|
-
end
|
|
12
|
+
attr_reader :commitref
|
|
21
13
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
Oxidized.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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 "
|
|
29
22
|
end
|
|
30
23
|
|
|
31
|
-
|
|
32
|
-
@cfg.
|
|
33
|
-
|
|
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
|
|
34
39
|
end
|
|
35
|
-
else
|
|
36
|
-
@cfg.repo = File.expand_path @cfg.repo
|
|
37
40
|
end
|
|
38
|
-
end
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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")
|
|
45
51
|
end
|
|
46
|
-
File.write(".gitattributes", "* filter=git-crypt diff=git-crypt\n.gitattributes !filter !diff")
|
|
47
|
-
repo.add(".gitattributes")
|
|
48
|
-
repo.commit("Initial commit: crypt all config files")
|
|
49
52
|
end
|
|
50
|
-
end
|
|
51
53
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
def lock(repo)
|
|
55
|
+
repo.chdir do
|
|
56
|
+
system(@gitcrypt_lock)
|
|
57
|
+
end
|
|
55
58
|
end
|
|
56
|
-
end
|
|
57
59
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
def unlock(repo)
|
|
61
|
+
repo.chdir do
|
|
62
|
+
system(@gitcrypt_unlock)
|
|
63
|
+
end
|
|
61
64
|
end
|
|
62
|
-
end
|
|
63
65
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
|
81
85
|
end
|
|
82
|
-
update type_repo,
|
|
86
|
+
update type_repo, file, type_cfg
|
|
83
87
|
end
|
|
84
|
-
update type_repo, file, type_cfg
|
|
85
|
-
end
|
|
86
88
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
update repo, file, outputs.to_cfg unless opt[:significant_changes] == false
|
|
90
|
+
end
|
|
89
91
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
|
103
105
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
+
# We keep :date for reverse compatibility on oxidized-web <= 0.15.1
|
|
118
|
+
hash[:date] = commit.date.to_s
|
|
119
|
+
# date as a Time instance for more flexibility in oxidized-web
|
|
120
|
+
hash[:time] = commit.date
|
|
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 StandardError
|
|
129
|
+
'node not found'
|
|
120
130
|
end
|
|
121
|
-
walker.reset
|
|
122
|
-
tab
|
|
123
|
-
rescue StandardError
|
|
124
|
-
'node not found'
|
|
125
|
-
end
|
|
126
131
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
132
|
+
# give the blob of a specific revision
|
|
133
|
+
def get_version(node, group, oid)
|
|
134
|
+
repo, path = yield_repo_and_path(node, group)
|
|
135
|
+
repo = Git.open repo
|
|
136
|
+
unlock repo
|
|
137
|
+
repo.gtree(oid).files[path].contents
|
|
138
|
+
rescue StandardError
|
|
139
|
+
'version not found'
|
|
140
|
+
ensure
|
|
141
|
+
lock repo
|
|
142
|
+
end
|
|
138
143
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
144
|
+
# give a hash with the patch of a diff between 2 revision and the stats (added and deleted lines)
|
|
145
|
+
def get_diff(node, group, oid1, oid2)
|
|
146
|
+
diff_commits = nil
|
|
147
|
+
repo, _path = yield_repo_and_path(node, group)
|
|
148
|
+
repo = Git.open repo
|
|
149
|
+
unlock repo
|
|
150
|
+
commit = repo.gcommit(oid1)
|
|
151
|
+
|
|
152
|
+
if oid2
|
|
153
|
+
commit_old = repo.gcommit(oid2)
|
|
154
|
+
diff = repo.diff(commit_old, commit)
|
|
155
|
+
stats = [diff.stats[:files][node.name][:insertions], diff.stats[:files][node.name][:deletions]]
|
|
156
|
+
diff.each do |patch|
|
|
157
|
+
if /#{node.name}\s+/ =~ patch.patch.to_s.lines.first
|
|
158
|
+
diff_commits = { patch: patch.patch.to_s, stat: stats }
|
|
159
|
+
break
|
|
160
|
+
end
|
|
155
161
|
end
|
|
162
|
+
else
|
|
163
|
+
stat = commit.parents[0].diff(commit).stats
|
|
164
|
+
stat = [stat[:files][node.name][:insertions], stat[:files][node.name][:deletions]]
|
|
165
|
+
patch = commit.parents[0].diff(commit).patch
|
|
166
|
+
diff_commits = { patch: patch, stat: stat }
|
|
156
167
|
end
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
168
|
+
lock repo
|
|
169
|
+
diff_commits
|
|
170
|
+
rescue StandardError
|
|
171
|
+
'no diffs'
|
|
172
|
+
ensure
|
|
173
|
+
lock repo
|
|
162
174
|
end
|
|
163
|
-
lock repo
|
|
164
|
-
diff_commits
|
|
165
|
-
rescue StandardError
|
|
166
|
-
'no diffs'
|
|
167
|
-
ensure
|
|
168
|
-
lock repo
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
private
|
|
172
175
|
|
|
173
|
-
|
|
174
|
-
repo, path = node.repo, node.name
|
|
176
|
+
private
|
|
175
177
|
|
|
176
|
-
|
|
178
|
+
def yield_repo_and_path(node, group)
|
|
179
|
+
repo = node.repo
|
|
180
|
+
path = node.name
|
|
177
181
|
|
|
178
|
-
|
|
179
|
-
end
|
|
182
|
+
path = "#{group}/#{node.name}" if group && @cfg.single_repo?
|
|
180
183
|
|
|
181
|
-
|
|
182
|
-
|
|
184
|
+
[repo, path]
|
|
185
|
+
end
|
|
183
186
|
|
|
184
|
-
|
|
185
|
-
if
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
187
|
+
def update(repo, file, data)
|
|
188
|
+
return if data.empty?
|
|
189
|
+
|
|
190
|
+
if @opt[:group]
|
|
191
|
+
if @cfg.single_repo?
|
|
192
|
+
file = ::File.join @opt[:group], file
|
|
193
|
+
else
|
|
194
|
+
repo = if repo.is_a?(::String)
|
|
195
|
+
::File.join ::File.dirname(repo), @opt[:group] + '.git'
|
|
196
|
+
else
|
|
197
|
+
repo[@opt[:group]]
|
|
198
|
+
end
|
|
199
|
+
end
|
|
193
200
|
end
|
|
194
|
-
end
|
|
195
201
|
|
|
196
|
-
begin
|
|
197
|
-
update_repo repo, file, data, @msg, @user, @email
|
|
198
|
-
rescue Git::GitExecuteError, ArgumentError => e
|
|
199
|
-
Oxidized.logger.debug "open_error #{e} #{file}"
|
|
200
202
|
begin
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
203
|
+
update_repo repo, file, data, @msg, @user, @email
|
|
204
|
+
rescue Git::GitExecuteError, ArgumentError => e
|
|
205
|
+
logger.debug "open_error #{e} #{file}"
|
|
206
|
+
begin
|
|
207
|
+
grepo = Git.init repo
|
|
208
|
+
crypt_init grepo
|
|
209
|
+
rescue StandardError => create_error
|
|
210
|
+
raise GitCryptError, "first '#{e.message}' was raised while opening git repo, then " \
|
|
211
|
+
"'#{create_error.message}' was while trying to create git repo"
|
|
212
|
+
end
|
|
213
|
+
retry
|
|
205
214
|
end
|
|
206
|
-
retry
|
|
207
215
|
end
|
|
208
|
-
end
|
|
209
216
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
217
|
+
def update_repo(repo, file, data, msg, user, email)
|
|
218
|
+
grepo = Git.open repo
|
|
219
|
+
grepo.config('user.name', user)
|
|
220
|
+
grepo.config('user.email', email)
|
|
221
|
+
grepo.chdir do
|
|
222
|
+
unlock grepo
|
|
223
|
+
::File.write(file, data)
|
|
224
|
+
grepo.add(file)
|
|
225
|
+
if grepo.status[file].nil? || !grepo.status[file].type.nil?
|
|
226
|
+
grepo.commit(msg)
|
|
227
|
+
@commitref = grepo.log(1).first.objectish
|
|
228
|
+
true
|
|
229
|
+
end
|
|
230
|
+
lock grepo
|
|
222
231
|
end
|
|
223
|
-
lock grepo
|
|
224
232
|
end
|
|
225
233
|
end
|
|
226
234
|
end
|
data/lib/oxidized/output/http.rb
CHANGED
|
@@ -1,61 +1,73 @@
|
|
|
1
1
|
module Oxidized
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
module Output
|
|
3
|
+
class Http < Output
|
|
4
|
+
attr_reader :commitref
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
def initialize
|
|
7
|
+
super
|
|
8
|
+
@cfg = Oxidized.config.output.http
|
|
9
|
+
end
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
def setup
|
|
12
|
+
return unless @cfg.empty?
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
|
20
|
+
|
|
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
|
+
|
|
30
|
+
# if uri scheme is https, enable ssl and set verify mode
|
|
31
|
+
if uri.scheme == "https"
|
|
32
|
+
http.use_ssl = true
|
|
33
|
+
http.verify_mode = @cfg.ssl_verify? ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
|
|
34
|
+
end
|
|
19
35
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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}"
|
|
36
|
+
headers = @cfg.headers? ? @cfg.headers : {}
|
|
37
|
+
|
|
38
|
+
req = Net::HTTP::Post.new(uri.request_uri, headers.merge('Content-Type' => 'application/json'))
|
|
39
|
+
req.basic_auth(@cfg.user, @cfg.password) if @cfg.user? && @cfg.password?
|
|
40
|
+
|
|
41
|
+
req.body = generate_json(node, outputs, opt)
|
|
42
|
+
response = http.request req
|
|
43
|
+
|
|
44
|
+
case response.code.to_i
|
|
45
|
+
when 200 || 201
|
|
46
|
+
logger.info "Configuration http backup complete for #{node}"
|
|
47
|
+
p [:success]
|
|
48
|
+
when (400..499)
|
|
49
|
+
logger.info "Configuration http backup for #{node} failed status: #{response.body}"
|
|
50
|
+
p [:bad_request]
|
|
51
|
+
when (500..599)
|
|
52
|
+
p [:server_problems]
|
|
53
|
+
logger.info "Configuration http backup for #{node} failed status: #{response.body}"
|
|
54
|
+
end
|
|
44
55
|
end
|
|
45
|
-
end
|
|
46
56
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def generate_json(node, outputs, opt)
|
|
60
|
+
JSON.pretty_generate(
|
|
61
|
+
'msg' => opt[:msg],
|
|
62
|
+
'user' => opt[:user],
|
|
63
|
+
'email' => opt[:email],
|
|
64
|
+
'group' => opt[:group],
|
|
65
|
+
'node' => node,
|
|
66
|
+
'config' => outputs.to_cfg
|
|
67
|
+
# actually we need to also iterate outputs, for other types like in gitlab.
|
|
68
|
+
# But most people don't use 'type' functionality.
|
|
69
|
+
)
|
|
70
|
+
end
|
|
59
71
|
end
|
|
60
72
|
end
|
|
61
73
|
end
|
|
@@ -1,9 +1,25 @@
|
|
|
1
1
|
module Oxidized
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
module Output
|
|
3
|
+
def self.clean_obsolete_nodes(active_nodes)
|
|
4
|
+
return unless Oxidized.config.output.clean_obsolete_nodes?
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
output_name = Oxidized.config.output.default
|
|
7
|
+
output = Oxidized.mgr.add_output output_name
|
|
8
|
+
output[output_name].clean_obsolete_nodes(active_nodes)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class Output
|
|
12
|
+
include SemanticLogger::Loggable
|
|
13
|
+
|
|
14
|
+
class NoConfig < OxidizedError; end
|
|
15
|
+
|
|
16
|
+
def cfg_to_str(cfg)
|
|
17
|
+
cfg.select { |h| h[:type] == 'cfg' }.map { |h| h[:data] }.join
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.clean_obsolete_nodes(_active_nodes)
|
|
21
|
+
logger.warn "clean_obsolete_nodes is not implemented for #{name}"
|
|
22
|
+
end
|
|
7
23
|
end
|
|
8
24
|
end
|
|
9
25
|
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Monkey patch Signal.trap for Puma to keep it from overriding our handlers
|
|
2
|
+
# Also prevent Puma from registering its own SIGHUP handler
|
|
3
|
+
module Puma
|
|
4
|
+
class Signal
|
|
5
|
+
class << self
|
|
6
|
+
alias os_trap trap
|
|
7
|
+
def Signal.trap(sig, &block)
|
|
8
|
+
sigshortname = sig.gsub "SIG", ''
|
|
9
|
+
Oxidized::Signals.register_signal(sig, block) unless sigshortname.eql? 'HUP'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
module Oxidized
|
|
16
|
+
class Signals
|
|
17
|
+
@handlers = Hash.new { |h, k| h[k] = [] }
|
|
18
|
+
class << self
|
|
19
|
+
attr_accessor :handlers
|
|
20
|
+
|
|
21
|
+
def register_signal(sig, procobj)
|
|
22
|
+
# Compute short name of the signal (without SIG prefix)
|
|
23
|
+
sigshortname = sig.gsub "SIG", ''
|
|
24
|
+
signum = Signal.list[sigshortname]
|
|
25
|
+
|
|
26
|
+
# Register the handler with OS
|
|
27
|
+
Signal.trap signum do
|
|
28
|
+
Oxidized::Signals.handle_signal(signum)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Add the proc to the handler list for the requested signal
|
|
32
|
+
@handlers[signum].push(procobj)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def handle_signal(signum)
|
|
36
|
+
return unless handlers.has_key?(signum)
|
|
37
|
+
|
|
38
|
+
@handlers[signum].each do |handler|
|
|
39
|
+
handler.call
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|