oxidized 0.33.0 → 0.34.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.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +4 -1
  3. data/.github/ISSUE_TEMPLATE/support-request.md +4 -1
  4. data/.github/workflows/ruby.yml +4 -2
  5. data/.gitignore +1 -0
  6. data/.rubocop.yml +29 -6
  7. data/.rubocop_todo.yml +2 -35
  8. data/CHANGELOG.md +49 -0
  9. data/CONTRIBUTING.md +10 -3
  10. data/Dockerfile +4 -4
  11. data/README.md +52 -55
  12. data/Rakefile +2 -3
  13. data/docs/Configuration.md +97 -0
  14. data/docs/DeviceSimulation.md +19 -7
  15. data/docs/Docker.md +9 -4
  16. data/docs/Issues.md +11 -2
  17. data/docs/ModelUnitTests.md +35 -25
  18. data/docs/Outputs.md +83 -2
  19. data/docs/Release.md +30 -22
  20. data/docs/Supported-OS-Types.md +4 -0
  21. data/docs/Troubleshooting.md +4 -18
  22. data/extra/device2yaml.rb +24 -9
  23. data/extra/rest_client.rb +2 -1
  24. data/extra/syslog.rb +8 -3
  25. data/lib/oxidized/cli.rb +7 -3
  26. data/lib/oxidized/config/vars.rb +7 -3
  27. data/lib/oxidized/config.rb +0 -1
  28. data/lib/oxidized/core.rb +5 -4
  29. data/lib/oxidized/hook/ciscosparkdiff.rb +11 -9
  30. data/lib/oxidized/hook/exec.rb +5 -4
  31. data/lib/oxidized/hook/githubrepo.rb +23 -17
  32. data/lib/oxidized/hook/noophook.rb +2 -2
  33. data/lib/oxidized/hook/slackdiff.rb +9 -8
  34. data/lib/oxidized/hook/xmppdiff.rb +9 -9
  35. data/lib/oxidized/hook.rb +10 -8
  36. data/lib/oxidized/input/cli.rb +8 -3
  37. data/lib/oxidized/input/exec.rb +1 -1
  38. data/lib/oxidized/input/ftp.rb +2 -2
  39. data/lib/oxidized/input/http.rb +5 -5
  40. data/lib/oxidized/input/input.rb +1 -0
  41. data/lib/oxidized/input/scp.rb +2 -2
  42. data/lib/oxidized/input/ssh.rb +21 -14
  43. data/lib/oxidized/input/telnet.rb +3 -3
  44. data/lib/oxidized/input/tftp.rb +1 -1
  45. data/lib/oxidized/job.rb +7 -4
  46. data/lib/oxidized/logger.rb +51 -0
  47. data/lib/oxidized/model/acos.rb +1 -0
  48. data/lib/oxidized/model/aos7.rb +6 -0
  49. data/lib/oxidized/model/aoscx.rb +2 -0
  50. data/lib/oxidized/model/aosw.rb +22 -17
  51. data/lib/oxidized/model/aricentiss.rb +2 -2
  52. data/lib/oxidized/model/asa.rb +3 -3
  53. data/lib/oxidized/model/awplus.rb +13 -10
  54. data/lib/oxidized/model/edgecos.rb +2 -1
  55. data/lib/oxidized/model/edgeos.rb +7 -6
  56. data/lib/oxidized/model/edgeswitch.rb +3 -1
  57. data/lib/oxidized/model/efos.rb +41 -0
  58. data/lib/oxidized/model/eltex.rb +1 -1
  59. data/lib/oxidized/model/fabricos.rb +1 -1
  60. data/lib/oxidized/model/fastiron.rb +3 -1
  61. data/lib/oxidized/model/firelinuxos.rb +12 -3
  62. data/lib/oxidized/model/fortios.rb +2 -1
  63. data/lib/oxidized/model/gaiaos.rb +4 -4
  64. data/lib/oxidized/model/ios.rb +15 -5
  65. data/lib/oxidized/model/ironware.rb +1 -1
  66. data/lib/oxidized/model/junos.rb +4 -0
  67. data/lib/oxidized/model/linksyssrw.rb +3 -3
  68. data/lib/oxidized/model/mlnxos.rb +14 -7
  69. data/lib/oxidized/model/model.rb +4 -3
  70. data/lib/oxidized/model/netgear.rb +2 -0
  71. data/lib/oxidized/model/nsxdfw.rb +2 -1
  72. data/lib/oxidized/model/nsxfirewall.rb +2 -1
  73. data/lib/oxidized/model/nxos.rb +2 -2
  74. data/lib/oxidized/model/openwrt.rb +6 -6
  75. data/lib/oxidized/model/procurve.rb +3 -1
  76. data/lib/oxidized/model/qtech.rb +3 -1
  77. data/lib/oxidized/model/quantaos.rb +8 -6
  78. data/lib/oxidized/model/routeros.rb +3 -2
  79. data/lib/oxidized/model/saos10.rb +38 -0
  80. data/lib/oxidized/model/sixwind.rb +28 -0
  81. data/lib/oxidized/model/sonicos.rb +1 -1
  82. data/lib/oxidized/model/supermicro.rb +1 -1
  83. data/lib/oxidized/model/timos.rb +1 -1
  84. data/lib/oxidized/model/tmos.rb +1 -0
  85. data/lib/oxidized/model/tnsr.rb +53 -0
  86. data/lib/oxidized/model/trango.rb +3 -1
  87. data/lib/oxidized/model/unifiap.rb +7 -5
  88. data/lib/oxidized/model/vrp.rb +3 -1
  89. data/lib/oxidized/model/xos.rb +3 -1
  90. data/lib/oxidized/model/zhoneolt.rb +3 -1
  91. data/lib/oxidized/model/zynos.rb +3 -3
  92. data/lib/oxidized/node.rb +44 -27
  93. data/lib/oxidized/nodes.rb +8 -4
  94. data/lib/oxidized/output/file.rb +28 -0
  95. data/lib/oxidized/output/git.rb +66 -9
  96. data/lib/oxidized/output/gitcrypt.rb +15 -13
  97. data/lib/oxidized/output/http.rb +5 -4
  98. data/lib/oxidized/output/output.rb +14 -0
  99. data/lib/oxidized/source/http.rb +4 -2
  100. data/lib/oxidized/version.rb +2 -2
  101. data/lib/oxidized/worker.rb +11 -8
  102. data/lib/oxidized.rb +3 -24
  103. data/oxidized.gemspec +8 -5
  104. metadata +54 -21
data/lib/oxidized/cli.rb CHANGED
@@ -1,5 +1,9 @@
1
+ require 'semantic_logger'
2
+
1
3
  module Oxidized
2
4
  class CLI
5
+ include SemanticLogger::Loggable
6
+
3
7
  require 'slop'
4
8
  require 'oxidized'
5
9
  require 'English'
@@ -9,7 +13,7 @@ module Oxidized
9
13
  Process.daemon if @opts[:daemonize]
10
14
  write_pid
11
15
  begin
12
- Oxidized.logger.info "Oxidized starting, running as pid #{$PROCESS_ID}"
16
+ logger.info "Oxidized starting, running as pid #{$PROCESS_ID}"
13
17
  Oxidized.new
14
18
  rescue StandardError => e
15
19
  crash e
@@ -23,13 +27,13 @@ module Oxidized
23
27
  _args, @opts = parse_opts
24
28
 
25
29
  Config.load(@opts)
26
- Oxidized.setup_logger
30
+ Oxidized::Logger.setup
27
31
 
28
32
  @pidfile = File.expand_path(Oxidized.config.pid)
29
33
  end
30
34
 
31
35
  def crash(error)
32
- Oxidized.logger.fatal "Oxidized crashed, crashfile written in #{Config::CRASH}"
36
+ logger.fatal "Oxidized crashed, crashfile written in #{Config::CRASH}"
33
37
  File.open Config::CRASH, 'w' do |file|
34
38
  file.puts '-' * 50
35
39
  file.puts Time.now.utc
@@ -6,11 +6,15 @@ module Oxidized
6
6
  model_name = @node.model.class.name.to_s.downcase
7
7
  if @node.vars&.has_key?(name)
8
8
  @node.vars[name]
9
- elsif Oxidized.config.groups.has_key?(@node.group) && Oxidized.config.groups[@node.group].models.has_key(model_name) && Oxidized.config.groups[@node.group].models[model_name].vars.has_key?(name.to_s)
9
+ elsif Oxidized.config.groups.has_key?(@node.group) &&
10
+ Oxidized.config.groups[@node.group].models.has_key(model_name) &&
11
+ Oxidized.config.groups[@node.group].models[model_name].vars.has_key?(name.to_s)
10
12
  Oxidized.config.groups[@node.group].models[model_name].vars[name.to_s]
11
- elsif Oxidized.config.groups.has_key?(@node.group) && Oxidized.config.groups[@node.group].vars.has_key?(name.to_s)
13
+ elsif Oxidized.config.groups.has_key?(@node.group) &&
14
+ Oxidized.config.groups[@node.group].vars.has_key?(name.to_s)
12
15
  Oxidized.config.groups[@node.group].vars[name.to_s]
13
- elsif Oxidized.config.models.has_key(model_name) && Oxidized.config.models[model_name].vars.has_key?(name.to_s)
16
+ elsif Oxidized.config.models.has_key(model_name) &&
17
+ Oxidized.config.models[model_name].vars.has_key?(name.to_s)
14
18
  Oxidized.config.models[model_name].vars[name.to_s]
15
19
  elsif Oxidized.config.vars.has_key?(name.to_s)
16
20
  Oxidized.config.vars[name.to_s]
@@ -27,7 +27,6 @@ module Oxidized
27
27
  asetus.default.model = 'junos'
28
28
  asetus.default.resolve_dns = true # if false, don't resolve DNS to IP
29
29
  asetus.default.interval = 3600
30
- asetus.default.use_syslog = false
31
30
  asetus.default.debug = false
32
31
  asetus.default.run_once = false
33
32
  asetus.default.threads = 30
data/lib/oxidized/core.rb CHANGED
@@ -6,6 +6,8 @@ module Oxidized
6
6
  end
7
7
 
8
8
  class Core
9
+ include SemanticLogger::Loggable
10
+
9
11
  class NoNodesFound < OxidizedError; end
10
12
 
11
13
  def initialize(_args)
@@ -33,7 +35,7 @@ module Oxidized
33
35
 
34
36
  # Initialize oxidized-web if requested
35
37
  if Oxidized.config.has_key? 'rest'
36
- Oxidized.logger.warn(
38
+ logger.warn(
37
39
  'configuration: "rest" is deprecated. Migrate to ' \
38
40
  '"extensions.oxidized-web" and remove "rest" from the configuration'
39
41
  )
@@ -61,14 +63,13 @@ module Oxidized
61
63
  private
62
64
 
63
65
  def reload
64
- Oxidized.logger.info("Reloading node list and log files")
66
+ logger.info("Reloading node list")
65
67
  @worker.reload
66
- Oxidized.logger.reopen
67
68
  @need_reload = false
68
69
  end
69
70
 
70
71
  def run
71
- Oxidized.logger.debug "lib/oxidized/core.rb: Starting the worker..."
72
+ logger.debug "Starting the worker..."
72
73
  loop do
73
74
  reload if @need_reload
74
75
  @worker.work
@@ -14,30 +14,32 @@ class CiscoSparkDiff < Oxidized::Hook
14
14
  return unless ctx.node
15
15
  return unless ctx.event.to_s == "post_store"
16
16
 
17
- log "Connecting to Cisco Spark"
17
+ logger.info "Connecting to Cisco Spark"
18
18
  CiscoSpark.configure do |config|
19
19
  config.api_key = cfg.accesskey
20
20
  config.proxy = cfg.proxy if cfg.has_key?('proxy')
21
21
  end
22
22
  room = CiscoSpark::Room.new(id: cfg.space)
23
- log "Connected"
23
+ logger.info "Connected"
24
24
 
25
25
  if cfg.has_key?("diff") ? cfg.diff : true
26
26
  gitoutput = ctx.node.output.new
27
27
  diff = gitoutput.get_diff ctx.node, ctx.node.group, ctx.commitref, nil
28
28
  title = ctx.node.name.to_s
29
- log "Posting diff as snippet to #{cfg.space}"
30
- room.send_message CiscoSpark::Message.new(text: 'Device ' + title + ' modified:' + "\n" + diff[:patch].lines.to_a[4..-1].join)
29
+ logger.info "Posting diff as snippet to #{cfg.space}"
30
+ room.send_message CiscoSpark::Message.new(text: "Device #{title} modified:\n" +
31
+ diff[:patch].lines.to_a[4..-1].join)
31
32
  end
32
33
 
33
34
  if cfg.message?
34
- log cfg.message
35
- msg = cfg.message % { node: ctx.node.name.to_s, group: ctx.node.group.to_s, commitref: ctx.commitref, model: ctx.node.model.class.name.to_s.downcase }
36
- log msg
37
- log "Posting message to #{cfg.space}"
35
+ logger.info cfg.message
36
+ msg = cfg.message % { node: ctx.node.name.to_s, group: ctx.node.group.to_s, commitref: ctx.commitref,
37
+ model: ctx.node.model.class.name.to_s.downcase }
38
+ logger.info msg
39
+ logger.info "Posting message to #{cfg.space}"
38
40
  room.send_message CiscoSpark::Message.new(text: msg)
39
41
  end
40
42
 
41
- log "Finished"
43
+ logger.info "Finished"
42
44
  end
43
45
  end
@@ -28,7 +28,7 @@ class Exec < Oxidized::Hook
28
28
 
29
29
  def run_hook(ctx)
30
30
  env = make_env ctx
31
- log "Execute: #{@cmd.inspect}", :debug
31
+ logger.debug "Execute: #{@cmd.inspect}"
32
32
  th = Thread.new do
33
33
  run_cmd! env
34
34
  rescue StandardError => e
@@ -38,20 +38,21 @@ class Exec < Oxidized::Hook
38
38
  end
39
39
 
40
40
  def run_cmd!(env)
41
- pid, status = nil, nil
41
+ pid = nil
42
+ status = nil
42
43
  Timeout.timeout(@timeout) do
43
44
  pid = spawn env, @cmd, unsetenv_others: true
44
45
  pid, status = wait2 pid
45
46
  unless status.exitstatus.zero?
46
47
  msg = "#{@cmd.inspect} failed with exit value #{status.exitstatus}"
47
- log msg, :error
48
+ logger.error msg
48
49
  raise msg
49
50
  end
50
51
  end
51
52
  rescue Timeout::Error
52
53
  kill "TERM", pid
53
54
  msg = "#{@cmd} timed out"
54
- log msg, :error
55
+ logger.error msg
55
56
  raise Timeout::Error, msg
56
57
  end
57
58
 
@@ -6,8 +6,13 @@ class GithubRepo < Oxidized::Hook
6
6
  end
7
7
 
8
8
  def run_hook(ctx)
9
+ unless ctx.node
10
+ logger.error 'GithubRepo.run_hook: no node provided'
11
+ return
12
+ end
13
+
9
14
  unless ctx.node.repo
10
- log "Oxidized output is not git, can't push to remote", :error
15
+ logger.error "Oxidized output is not git, can't push to remote"
11
16
  return
12
17
  end
13
18
  repo = Rugged::Repository.new(ctx.node.repo)
@@ -15,12 +20,11 @@ class GithubRepo < Oxidized::Hook
15
20
  url = remote_repo(ctx.node)
16
21
 
17
22
  if url.nil? || url.empty?
18
- log "No repository defined for #{ctx.node.group}/#{ctx.node.name}", :error
23
+ logger.error "No repository defined for #{ctx.node.group}/#{ctx.node.name}"
19
24
  return
20
25
  end
21
26
 
22
- log "Pushing local repository(#{repo.path})..."
23
- log "to remote: #{url}"
27
+ logger.info "Pushing local repository(#{repo.path}) to remote: #{url}"
24
28
 
25
29
  if repo.remotes['origin'].nil?
26
30
  repo.remotes.create('origin', url)
@@ -34,10 +38,10 @@ class GithubRepo < Oxidized::Hook
34
38
  remote.push([repo.head.name], credentials: creds)
35
39
  rescue Rugged::NetworkError => e
36
40
  if e.message == 'unsupported URL protocol'
37
- log "Rugged does not support the git URL '#{url}'.", :warn
41
+ logger.warn "Rugged does not support the git URL '#{url}'."
38
42
  unless Rugged.features.include?(:ssh)
39
- log 'You may need to install Rugged with ssh support ' \
40
- '(gem install rugged -- --with-ssh)', :warn
43
+ logger.warn "Note: Rugged isn't installed with ssh support. You may need " \
44
+ '"gem install rugged -- --with-ssh"'
41
45
  end
42
46
  end
43
47
  # re-raise exception for the calling method
@@ -47,28 +51,28 @@ class GithubRepo < Oxidized::Hook
47
51
 
48
52
  def fetch_and_merge_remote(repo, creds)
49
53
  result = repo.fetch('origin', [repo.head.name], credentials: creds)
50
- log result.inspect, :debug
54
+ logger.debug result.inspect
51
55
 
52
56
  their_branch = remote_branch(repo)
53
57
 
54
58
  unless their_branch
55
- log 'remote branch does not exist yet, nothing to merge', :debug
59
+ logger.debug 'remote branch does not exist yet, nothing to merge'
56
60
  return
57
61
  end
58
62
 
59
63
  result = repo.merge_analysis(their_branch.target_id)
60
64
 
61
65
  if result.include? :up_to_date
62
- log 'nothing to merge', :debug
66
+ logger.debug 'nothing to merge'
63
67
  return
64
68
  end
65
69
 
66
- log "merging fetched branch #{their_branch.name}", :debug
70
+ logger.debug "merging fetched branch #{their_branch.name}"
67
71
 
68
72
  merge_index = repo.merge_commits(repo.head.target_id, their_branch.target_id)
69
73
 
70
74
  if merge_index.conflicts?
71
- log("Conflicts detected, skipping Rugged::Commit.create", :warn)
75
+ logger.warn "Conflicts detected, skipping Rugged::Commit.create"
72
76
  return
73
77
  end
74
78
 
@@ -85,18 +89,20 @@ class GithubRepo < Oxidized::Hook
85
89
  Proc.new do |_url, username_from_url, _allowed_types| # rubocop:disable Style/Proc
86
90
  git_user = cfg.has_key?('username') ? cfg.username : (username_from_url || 'git')
87
91
  if cfg.has_key?('password')
88
- log "Authenticating using username and password as '#{git_user}'", :debug
92
+ logger.debug "Authenticating using username and password as '#{git_user}'"
89
93
  Rugged::Credentials::UserPassword.new(username: git_user, password: cfg.password)
90
94
  elsif cfg.has_key?('privatekey')
91
95
  pubkey = cfg.has_key?('publickey') ? cfg.publickey : nil
92
- log "Authenticating using ssh keys as '#{git_user}'", :debug
96
+ logger.debug "Authenticating using ssh keys as '#{git_user}'"
93
97
  rugged_sshkey(git_user: git_user, privkey: cfg.privatekey, pubkey: pubkey)
94
- elsif cfg.has_key?('remote_repo') && cfg.remote_repo.has_key?(node.group) && cfg.remote_repo[node.group].has_key?('privatekey')
98
+ elsif cfg.has_key?('remote_repo') &&
99
+ cfg.remote_repo.has_key?(node.group) &&
100
+ cfg.remote_repo[node.group].has_key?('privatekey')
95
101
  pubkey = cfg.remote_repo[node.group].has_key?('publickey') ? cfg.remote_repo[node.group].publickey : nil
96
- log "Authenticating using ssh keys as '#{git_user}' for '#{node.group}/#{node.name}'", :debug
102
+ logger.debug "Authenticating using ssh keys as '#{git_user}' for '#{node.group}/#{node.name}'"
97
103
  rugged_sshkey(git_user: git_user, privkey: cfg.remote_repo[node.group].privatekey, pubkey: pubkey)
98
104
  else
99
- log "Authenticating using ssh agent as '#{git_user}'", :debug
105
+ logger.debug "Authenticating using ssh agent as '#{git_user}'"
100
106
  Rugged::Credentials::SshKeyFromAgent.new(username: git_user)
101
107
  end
102
108
  end
@@ -1,9 +1,9 @@
1
1
  class NoopHook < Oxidized::Hook
2
2
  def validate_cfg!
3
- log "Validate config"
3
+ logger.info "Validate config"
4
4
  end
5
5
 
6
6
  def run_hook(ctx)
7
- log "Run hook with context: #{ctx}"
7
+ logger.info "Run hook with context: #{ctx}"
8
8
  end
9
9
  end
@@ -12,7 +12,7 @@ class SlackDiff < Oxidized::Hook
12
12
  end
13
13
 
14
14
  def slack_upload(client, title, content, channel)
15
- log "Posting diff as snippet to #{channel}"
15
+ logger.info "Posting diff as snippet to #{channel}"
16
16
  upload_dest = client.files_getUploadURLExternal(filename: "change",
17
17
  length: content.length,
18
18
  snippet_type: "diff")
@@ -39,14 +39,14 @@ class SlackDiff < Oxidized::Hook
39
39
  return unless ctx.node
40
40
  return unless ctx.event.to_s == "post_store"
41
41
 
42
- log "Connecting to slack"
42
+ logger.info "Connecting to slack"
43
43
  Slack::Web::Client.configure do |config|
44
44
  config.token = cfg.token
45
45
  config.proxy = cfg.proxy if cfg.has_key?('proxy')
46
46
  end
47
47
  client = Slack::Web::Client.new
48
48
  client.auth_test
49
- log "Connected"
49
+ logger.info "Connected"
50
50
  if cfg.has_key?("diff") ? cfg.diff : true
51
51
  gitoutput = ctx.node.output.new
52
52
  diff = gitoutput.get_diff ctx.node, ctx.node.group, ctx.commitref, nil
@@ -58,12 +58,13 @@ class SlackDiff < Oxidized::Hook
58
58
  end
59
59
  # message custom formatted - optional
60
60
  if cfg.message?
61
- log cfg.message
62
- msg = cfg.message % { node: ctx.node.name.to_s, group: ctx.node.group.to_s, commitref: ctx.commitref, model: ctx.node.model.class.name.to_s.downcase }
63
- log msg
64
- log "Posting message to #{cfg.channel}"
61
+ logger.info cfg.message
62
+ msg = cfg.message % { node: ctx.node.name.to_s, group: ctx.node.group.to_s, commitref: ctx.commitref,
63
+ model: ctx.node.model.class.name.to_s.downcase }
64
+ logger.info msg
65
+ logger.info "Posting message to #{cfg.channel}"
65
66
  client.chat_postMessage(channel: cfg.channel, text: msg, as_user: true)
66
67
  end
67
- log "Finished"
68
+ logger.info "Finished"
68
69
  end
69
70
  end
@@ -5,35 +5,35 @@ class XMPPDiff < Oxidized::Hook
5
5
  def connect
6
6
  @client = Jabber::Client.new(Jabber::JID.new(cfg.jid))
7
7
 
8
- log "Connecting to XMPP"
8
+ logger.info "Connecting to XMPP"
9
9
  begin
10
10
  Timeout.timeout(15) do
11
11
  begin
12
12
  @client.connect
13
13
  rescue StandardError => e
14
- log "Failed to connect to XMPP: #{e}"
14
+ logger.info "Failed to connect to XMPP: #{e}"
15
15
  end
16
16
  sleep 1
17
17
 
18
- log "Authenticating to XMPP"
18
+ logger.info "Authenticating to XMPP"
19
19
  @client.auth(cfg.password)
20
20
  sleep 1
21
21
 
22
- log "Connected to XMPP"
22
+ logger.info "Connected to XMPP"
23
23
 
24
24
  @muc = Jabber::MUC::SimpleMUCClient.new(@client)
25
25
  @muc.join(cfg.channel + "/" + cfg.nick)
26
26
 
27
- log "Joined #{cfg.channel}"
27
+ logger.info "Joined #{cfg.channel}"
28
28
  end
29
29
  rescue Timeout::Error
30
- log "timed out"
30
+ logger.info "timed out"
31
31
  @client = nil
32
32
  @muc = nil
33
33
  end
34
34
 
35
35
  @client.on_exception do
36
- log "XMPP connection aborted, reconnecting"
36
+ logger.info "XMPP connection aborted, reconnecting"
37
37
  @client = nil
38
38
  @muc = nil
39
39
  connect
@@ -66,14 +66,14 @@ class XMPPDiff < Oxidized::Hook
66
66
  # Maybe connecting failed, so only proceed if we actually joined the MUC
67
67
  unless @muc.nil?
68
68
  title = "#{ctx.node.name} #{ctx.node.group} #{ctx.node.model.class.name.to_s.downcase}"
69
- log "Posting diff as snippet to #{cfg.channel}"
69
+ logger.info "Posting diff as snippet to #{cfg.channel}"
70
70
 
71
71
  @muc.say(title + "\n\n" + diff[:patch].lines.to_a[4..-1].join)
72
72
  end
73
73
  end
74
74
  end
75
75
  rescue Timeout::Error
76
- log "timed out"
76
+ logger.info "timed out"
77
77
  end
78
78
  end
79
79
  end
data/lib/oxidized/hook.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  module Oxidized
2
2
  class HookManager
3
+ include SemanticLogger::Loggable
4
+
3
5
  class << self
4
6
  def from_config(cfg)
5
7
  mgr = new
@@ -14,7 +16,9 @@ module Oxidized
14
16
 
15
17
  # HookContext is passed to each hook. It can contain anything related to the
16
18
  # event in question. At least it contains the event name
17
- class HookContext < OpenStruct; end
19
+ # The argument keyword_init: true is needed for ruby < 3.2 and can be
20
+ # dropped with the support of ruby 3.1
21
+ HookContext = Struct.new(:event, :node, :job, :commitref, keyword_init: true)
18
22
 
19
23
  # RegisteredHook is a container for a Hook instance
20
24
  RegisteredHook = Struct.new(:name, :hook)
@@ -47,7 +51,7 @@ module Oxidized
47
51
  hook.cfg = cfg
48
52
 
49
53
  @registered_hooks[event] << RegisteredHook.new(name, hook)
50
- Oxidized.logger.debug "Hook #{name.inspect} registered #{hook.class} for event #{event.inspect}"
54
+ logger.debug "Hook #{name.inspect} registered #{hook.class} for event #{event.inspect}"
51
55
  end
52
56
 
53
57
  def handle(event, ctx_params = {})
@@ -57,14 +61,16 @@ module Oxidized
57
61
  @registered_hooks[event].each do |r_hook|
58
62
  r_hook.hook.run_hook ctx
59
63
  rescue StandardError => e
60
- Oxidized.logger.error "Hook #{r_hook.name} (#{r_hook.hook}) failed " \
61
- "(#{e.inspect}) for event #{event.inspect}"
64
+ logger.error "Hook #{r_hook.name} (#{r_hook.hook}) failed " \
65
+ "(#{e.inspect}) for event #{event.inspect}"
62
66
  end
63
67
  end
64
68
  end
65
69
 
66
70
  # Hook abstract base class
67
71
  class Hook
72
+ include SemanticLogger::Loggable
73
+
68
74
  attr_reader :cfg
69
75
 
70
76
  def cfg=(cfg)
@@ -75,9 +81,5 @@ module Oxidized
75
81
  def run_hook(_ctx)
76
82
  raise NotImplementedError
77
83
  end
78
-
79
- def log(msg, level = :info)
80
- Oxidized.logger.send(level, "#{self.class.name}: #{msg}")
81
- end
82
84
  end
83
85
  end
@@ -20,15 +20,16 @@ module Oxidized
20
20
  end
21
21
 
22
22
  def connect_cli
23
- Oxidized.logger.debug "lib/oxidized/input/cli.rb: Running post_login commands at #{node.name}"
23
+ logger.debug "Running post_login commands at #{node.name}"
24
24
  @post_login.each do |command, block|
25
- Oxidized.logger.debug "lib/oxidized/input/cli.rb: Running post_login command: #{command.inspect}, block: #{block.inspect} at #{node.name}"
25
+ logger.debug "Running post_login command: #{command.inspect}, " \
26
+ "block: #{block.inspect} at #{node.name}"
26
27
  block ? block.call : (cmd command)
27
28
  end
28
29
  end
29
30
 
30
31
  def disconnect_cli
31
- Oxidized.logger.debug "lib/oxidized/input/cli.rb Running pre_logout commands at #{node.name}"
32
+ logger.debug "Running pre_logout commands at #{node.name}"
32
33
  @pre_logout.each { |command, block| block ? block.call : (cmd command, nil) }
33
34
  end
34
35
 
@@ -52,6 +53,10 @@ module Oxidized
52
53
  @password || (@password = regex)
53
54
  end
54
55
 
56
+ def newline(newline_str = "\n")
57
+ @newline || (@newline = newline_str)
58
+ end
59
+
55
60
  def login
56
61
  match_re = [@node.prompt]
57
62
  match_re << @username if @username
@@ -11,7 +11,7 @@ module Oxidized
11
11
  end
12
12
 
13
13
  def cmd(cmd_str)
14
- Oxidized.logger.debug "EXEC: #{cmd_str} @ #{@node.name}"
14
+ logger.debug "EXEC: #{cmd_str} @ #{@node.name}"
15
15
  # I'd really like to do popen3 with separate arguments, but that would
16
16
  # require refactoring cmd to take parameters
17
17
  %x(#{cmd_str})
@@ -15,7 +15,7 @@ module Oxidized
15
15
  }.freeze
16
16
  include Input::CLI
17
17
 
18
- def connect(node)
18
+ def connect(node) # rubocop:disable Naming/PredicateMethod
19
19
  @node = node
20
20
  @node.model.cfg['ftp'].each { |cb| instance_exec(&cb) }
21
21
  @log = File.open(Oxidized::Config::LOG + "/#{@node.ip}-ftp", 'w') if Oxidized.config.input.debug?
@@ -30,7 +30,7 @@ module Oxidized
30
30
  end
31
31
 
32
32
  def cmd(file)
33
- Oxidized.logger.debug "FTP: #{file} @ #{@node.name}"
33
+ logger.debug "FTP: #{file} @ #{@node.name}"
34
34
  @ftp.getbinaryfile file, nil
35
35
  end
36
36
 
@@ -51,7 +51,7 @@ module Oxidized
51
51
  schema = @secure ? "https://" : "http://"
52
52
  uri = URI("#{schema}#{@node.ip}#{path}")
53
53
 
54
- Oxidized.logger.debug "Making request to: #{uri}"
54
+ logger.debug "Making request to: #{uri}"
55
55
 
56
56
  ssl_verify = Oxidized.config.input.http.ssl_verify? ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
57
57
 
@@ -60,16 +60,16 @@ module Oxidized
60
60
  if res.code == '401' && res['www-authenticate']&.include?('Digest')
61
61
  uri.user = @username
62
62
  uri.password = URI.encode_www_form_component(@password)
63
- Oxidized.logger.debug "Server requires Digest authentication"
63
+ logger.debug "Server requires Digest authentication"
64
64
  auth = Net::HTTP::DigestAuth.new.auth_header(uri, res['www-authenticate'], 'GET')
65
65
 
66
66
  res = make_request(uri, ssl_verify, 'Authorization' => auth)
67
67
  elsif @username && @password
68
- Oxidized.logger.debug "Falling back to Basic authentication"
68
+ logger.debug "Falling back to Basic authentication"
69
69
  res = make_request(uri, ssl_verify, 'Authorization' => basic_auth_header)
70
70
  end
71
71
 
72
- Oxidized.logger.debug "Response code: #{res.code}"
72
+ logger.debug "Response code: #{res.code}"
73
73
  res.body
74
74
  end
75
75
 
@@ -77,7 +77,7 @@ module Oxidized
77
77
  Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https", verify_mode: ssl_verify) do |http|
78
78
  req = Net::HTTP::Get.new(uri)
79
79
  @headers.merge(extra_headers).each { |header, value| req.add_field(header, value) }
80
- Oxidized.logger.debug "Sending request with headers: #{@headers.merge(extra_headers)}"
80
+ logger.debug "Sending request with headers: #{@headers.merge(extra_headers)}"
81
81
  http.request(req)
82
82
  end
83
83
  end
@@ -2,6 +2,7 @@ module Oxidized
2
2
  class PromptUndetect < OxidizedError; end
3
3
 
4
4
  class Input
5
+ include SemanticLogger::Loggable
5
6
  include Oxidized::Config::Vars
6
7
 
7
8
  RESCUE_FAIL = {
@@ -16,7 +16,7 @@ module Oxidized
16
16
  }.freeze
17
17
  include Input::CLI
18
18
 
19
- def connect(node)
19
+ def connect(node) # rubocop:disable Naming/PredicateMethod
20
20
  @node = node
21
21
  @node.model.cfg['scp'].each { |cb| instance_exec(&cb) }
22
22
  @log = File.open(Oxidized::Config::LOG + "/#{@node.ip}-scp", 'w') if Oxidized.config.input.debug?
@@ -29,7 +29,7 @@ module Oxidized
29
29
  end
30
30
 
31
31
  def cmd(file)
32
- Oxidized.logger.debug "SCP: #{file} @ #{@node.name}"
32
+ logger.debug "SCP: #{file} @ #{@node.name}"
33
33
  @ssh.scp.download!(file)
34
34
  end
35
35