forked from normelton/snmp4em
/
snmp_set_request.rb
94 lines (72 loc) · 2.92 KB
/
snmp_set_request.rb
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
module SNMP4EM
# Returned from SNMP4EM::SNMPv1.set(). This implements EM::Deferrable, so you can hang a callback()
# or errback() to retrieve the results.
class SnmpSetRequest < SnmpRequest
attr_accessor :snmp_id
# For an SNMP-SET request, @pending_varbinds will by an SNMP::VarBindList, initially populated from the
# provided oids hash. Variables can be passed as specific types from the SNMP library (i.e. SNMP::IpAddress)
# or as ruby native objects, in which case they will be cast into the appropriate SNMP object. As responses
# are returned, the @pending_varbinds object will be pruned of any error-producing varbinds. Once no errors
# are produced, the @responses object is populated and returned.
def initialize(sender, oids, args = {}) #:nodoc:
_oids = [*oids]
@sender = sender
@timeout_timer = nil
@timeout_retries = @sender.retries
@error_retries = _oids.size
@return_raw = args[:return_raw] || false
@responses = Hash.new
@pending_varbinds = SNMP::VarBindList.new()
_oids.each do |oid,value|
if value.is_a? Integer
snmp_value = SNMP::Integer.new(value)
elsif value.is_a? String
snmp_value = SNMP::OctetString.new(value)
else
snmp_value = value
end
@pending_varbinds << SNMP::VarBind.new(oid,snmp_value)
end
init_callbacks
send
end
def handle_response(response) #:nodoc:
if (response.error_status == :noError)
# No errors, set any remaining varbinds to true
response.each_varbind do |vb|
response_vb = @pending_varbinds.shift
@responses[response_vb.name.to_s] = true
end
else
# Got an error, remove that varbind from @pending_varbinds so we can try again
error_vb = @pending_varbinds.delete_at(response.error_index - 1)
@responses[error_vb.name.to_s] = SNMP::ResponseError.new(response.error_status)
end
if (@pending_varbinds.empty? || @error_retries.zero?)
until @pending_varbinds.empty?
error_vb = @pending_varbinds.shift
@responses[error_vb.name.to_s] = SNMP::ResponseError.new(:genErr)
end
unless @return_raw
@responses.each_pair do |oid, value|
@responses[oid] = value.rubify if value.respond_to?(:rubify)
end
end
# Send the @responses back to the requester, we're done!
succeed @responses
else
@error_retries -= 1
send
end
end
private
def send
Manager.track_request(self)
# Send the contents of @pending_varbinds
vb_list = SNMP::VarBindList.new(@pending_varbinds)
request = SNMP::SetRequest.new(@snmp_id, vb_list)
message = SNMP::Message.new(@sender.version, @sender.community_ro, request)
super(message)
end
end
end