blob: f27efe5e4961de159163066b944fd2730045dada (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
# encoding: UTF-8
require 'ipaddr'
require 'resolv'
require 'socket'
require 'mauve/mauve_time'
module Mauve
class Sender
DEFAULT_PORT = 32741
include Resolv::DNS::Resource::IN
def initialize(*destinations)
destinations = destinations.flatten
destinations = begin
File.read("/etc/mauvealert/mauvesend.destination").split(/\s+/)
rescue Errno::ENOENT => notfound
[]
end if destinations.empty?
if !destinations || destinations.empty?
raise ArgumentError.new("No destinations specified, and could not read any destinations from /etc/mauvealert/mauvesend.destination")
end
@destinations = destinations.map do |spec|
next_spec = begin
# FIXME: for IPv6
port = spec.split(":")[1] || DEFAULT_PORT
IPAddr.new(spec.split(":")[0])
["#{spec}:#{port}"]
rescue ArgumentError => not_an_ip_address
Resolv::DNS.open do |dns|
srv_spec = spec[0] == ?_ ? spec : "_mauvealert._udp.#{spec}"
list = dns.getresources(srv_spec, SRV).map do |srv|
srv.target.to_s + ":#{srv.port}"
end
list = [spec] if list.empty?
list.map do |spec2|
spec2_addr, spec2_port = spec2.split(":")
spec2_port ||= DEFAULT_PORT
dns.getresources(spec2_addr, A).map do |a|
"#{a.address}:#{spec2_port}"
end
end
end
end.flatten
error "Can't resolve destination #{spec}" if next_spec.empty?
next_spec
end.
flatten.
uniq
end
def send(update, verbose=0)
#
# Must have a source, so default to hostname if user doesn't care
update.source ||= `hostname -f`.chomp
#
# Make sure all alerts default to "-r now"
#
update.alert.each do |alert|
next if alert.raise_time || alert.clear_time
alert.raise_time = MauveTime.now.to_i
end
#
# Make sure we set the transmission time
#
update.transmission_time = MauveTime.now.to_i
data = update.serialize_to_string
if verbose == 1
print "#{update.transmission_id}\n"
elsif verbose >= 2
print "Sending #{update.inspect.chomp} to #{@destinations.join(", ")}\n"
end
@destinations.each do |spec|
UDPSocket.open do |sock|
ip = spec.split(":")[0]
port = spec.split(":")[1].to_i
sock.send(data, 0, ip, port)
end
end
end
end
end
|