Class: Hotwired::SNMP

Inherits:
Object
  • Object
show all
Defined in:
lib/hotwired/snmp.rb

Defined Under Namespace

Classes: InvalidResponse

Constant Summary collapse

DB_OID =

需要遍历 oid 写入数据库的相关属性

{
  sysDescr: "1.3.6.1.2.1.1.1.0", # 运行系统描述
  sysObjectID: "1.3.6.1.2.1.1.2.0", # 厂商识别
  sysName: "1.3.6.1.2.1.1.5.0", # 系统名称
  sysLocation: "1.3.6.1.2.1.1.6.0", # 系统位置
}
OID =
{
  ifDescr: "1.3.6.1.2.1.2.2.1.2", # 接口描述
  ipCidrRouteIfIndex: "1.3.6.1.2.1.4.24.4.1.5", # addr.255.255.255.255.0.0.0.0.0
  ipAdEntIfIndex: "1.3.6.1.2.1.4.20.1.2", # addr | 旧格式
  ipAddressIfIndex: "1.3.6.1.2.1.4.34.1.3", # 1,2 (uni,any) . 4,16 (size) . addr | 新格式
}
UNICAST =

1,2 (uni,any) . 4,16 (size) . addr | 新格式

1
IPV4 =
4
BULK_MAX =
30

Instance Method Summary collapse

Constructor Details

#initialize(host, community = CFG.community) ⇒ SNMP

类对象初始化函数入口



28
29
30
# File 'lib/hotwired/snmp.rb', line 28

def initialize(host, community = CFG.community)
  @snmp = ::SNMP::Manager.new(Host: host, Community: community, Timeout: CFG.timeout, Retries: CFG.retries, MibModules: [])
end

Instance Method Details

#bulkwalk(root) ⇒ Object

遍历根节点检索数据



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/hotwired/snmp.rb', line 79

def bulkwalk(root)
  # 初始化遍历
  last, oid, vbs = false, root, []
  # 轮询 root oid 主体逻辑
  until last
    r = @snmp.get_bulk 0, BULK_MAX, oid
    r.varbind_list.each do |vb|
      oid = vb.name.to_str
      # 跳出循环条件
      (last = true; break) unless oid.match?(/^#{Regexp.quote root}/)
      vbs << vb
    end
  end
  vbs
end

#closeObject

关闭会话



33
34
35
# File 'lib/hotwired/snmp.rb', line 33

def close
  @snmp.close
end

#get(*oid) ⇒ Object

查询 oid 监控数据 支持多个片段拼接成一个完整的 OID 字串



39
40
41
42
43
44
45
46
47
# File 'lib/hotwired/snmp.rb', line 39

def get(*oid)
  oid = [oid].flatten.join(".")
  begin
    @snmp.get(oid).each_varbind { |vb| return vb }
  rescue ::SNMP::RequestTimeout, Errno::EACCES
    Log.debug "::SNMP::RequestTimeout, Errno::EACCES when get(*oid)"
    nil
  end
end

#ifdescr(index) ⇒ Object

查询接口描述



116
117
118
119
120
# File 'lib/hotwired/snmp.rb', line 116

def ifdescr(index)
  descr = get OID[:ifDescr], index
  return nil unless descr && (descr.value.class == ::SNMP::OctetString)
  descr.value.to_s
end

#ip2index(ip) ⇒ Object

IP 转索引



101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/hotwired/snmp.rb', line 101

def ip2index(ip)
  # 根据 IP 查询其路由及接口IP索引序号
  oids = mget(route: [OID[:ipCidrRouteIfIndex], ip, "255.255.255.255.0.0.0.0.0"].join("."),
              new:   [OID[:ipAddressIfIndex], UNICAST, IPV4, ip].join("."),
              old:   [OID[:ipAdEntIfIndex], ip].join("."))
  return nil unless oids
  # 优先使用 route 命中,如查询不到则进一步尝试使用其他属性
  index = oids[:route]
  index = oids[:new] if (not index.class == ::SNMP::Integer) || (index.to_s == "0")
  index = oids[:old] if (not index.class == ::SNMP::Integer) || (index.to_s == "0")
  return nil unless index.class == ::SNMP::Integer
  index.to_s
end

#mget(oids = DB_OID) ⇒ Object Also known as: dbget

批量查询 oid,入参为 HASH 数据结构



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/hotwired/snmp.rb', line 50

def mget(oids = DB_OID)
  result = {}
  begin
    res = @snmp.get(oids.map { |_, oid| oid })
    # 抛出异常
    raise InvalidResponse, "#{res.error_status} from #{@snmp.config[:host]}" unless res.error_status == :noError
    res.each_varbind do |vb|
      oids.each do |key, oid|
        if vb.name.to_str == oid
          result[key] = vb.value
          # 找到即跳出当前循环体
          next
        end
      end
    end
  rescue ::SNMP::RequestTimeout, Errno::EACCES
    Log.debug "::SNMP::RequestTimeout, Errno::EACCES when mget"
    return nil
  rescue InvalidResponse
    Log.debug "InvalidResponse when mget(oids = {})"
    return nil
  end
  result
end

#sysdescrObject

查询设备描述



96
97
98
# File 'lib/hotwired/snmp.rb', line 96

def sysdescr
  get DB_OID[:sysDescr]
end