Added hardware agent's inspector and snmp implementation
Added the inspector interface to hardware agent, also added the snmp implementation of that inspector. Implements: blueprint monitoring-physical-devices Based on the original code at https://github.com/graflu0/ceilometer contributed by Lucas and Toni. Change-Id: I7cbaf94d72d389dc802c42b6ca8939b81a1d6b10 Signed-off-by: Lucas Graf <graflu0@students.zhaw.ch> Signed-off-by: Toni Zehnder <zehndton@students.zhaw.ch> Signed-off-by: Lianhao Lu <lianhao.lu@intel.com>
This commit is contained in:
parent
6bdeed760e
commit
4e72e0273f
0
ceilometer/hardware/__init__.py
Normal file
0
ceilometer/hardware/__init__.py
Normal file
29
ceilometer/hardware/inspector/__init__.py
Normal file
29
ceilometer/hardware/inspector/__init__.py
Normal file
@ -0,0 +1,29 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# Copyright © 2014 Intel Corp.
|
||||
#
|
||||
# Author: Lianhao Lu <yunhong.jiang@intel.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from stevedore import driver
|
||||
|
||||
|
||||
def get_inspector(parsed_url, namespace='ceilometer.hardware.inspectors'):
|
||||
"""Get inspector driver and load it.
|
||||
|
||||
:param parsed_url: urlparse.SplitResult object for the inspector
|
||||
:param namespace: Namespace to use to look for drivers.
|
||||
"""
|
||||
loaded_driver = driver.DriverManager(namespace, parsed_url.scheme)
|
||||
return loaded_driver.driver()
|
111
ceilometer/hardware/inspector/base.py
Normal file
111
ceilometer/hardware/inspector/base.py
Normal file
@ -0,0 +1,111 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# Copyright © 2014 ZHAW SoE
|
||||
#
|
||||
# Authors: Lucas Graf <graflu0@students.zhaw.ch>
|
||||
# Toni Zehnder <zehndton@students.zhaw.ch>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Inspector abstraction for read-only access to hardware components"""
|
||||
|
||||
import abc
|
||||
import collections
|
||||
|
||||
import six
|
||||
|
||||
# Named tuple representing CPU statistics.
|
||||
#
|
||||
# cpu1MinLoad: 1 minute load
|
||||
# cpu5MinLoad: 5 minute load
|
||||
# cpu15MinLoad: 15 minute load
|
||||
#
|
||||
CPUStats = collections.namedtuple(
|
||||
'CPUStats',
|
||||
['cpu_1_min', 'cpu_5_min', 'cpu_15_min'])
|
||||
|
||||
# Named tuple representing RAM statistics.
|
||||
#
|
||||
# total: Total Memory (bytes)
|
||||
# used: Used Memory (bytes)
|
||||
#
|
||||
MemoryStats = collections.namedtuple('MemoryStats', ['total', 'used'])
|
||||
|
||||
# Named tuple representing disks.
|
||||
#
|
||||
# device: the device name for the disk
|
||||
# path: the path from the disk
|
||||
#
|
||||
Disk = collections.namedtuple('Disk', ['device', 'path'])
|
||||
|
||||
# Named tuple representing disk statistics.
|
||||
#
|
||||
# size: storage size (bytes)
|
||||
# used: storage used (bytes)
|
||||
#
|
||||
DiskStats = collections.namedtuple('DiskStats', ['size', 'used'])
|
||||
|
||||
|
||||
# Named tuple representing an interface.
|
||||
#
|
||||
# name: the name of the interface
|
||||
# mac: the MAC of the interface
|
||||
# ip: the IP of the interface
|
||||
#
|
||||
Interface = collections.namedtuple('Interface', ['name', 'mac', 'ip'])
|
||||
|
||||
|
||||
# Named tuple representing network interface statistics.
|
||||
#
|
||||
# bandwidth: current bandwidth (bytes/s)
|
||||
# rx_bytes: total number of octets received (bytes)
|
||||
# tx_bytes: total number of octets transmitted (bytes)
|
||||
# error: number of outbound packets not transmitted because of errors
|
||||
#
|
||||
InterfaceStats = collections.namedtuple(
|
||||
'InterfaceStats',
|
||||
['bandwidth', 'rx_bytes', 'tx_bytes', 'error'])
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class Inspector(object):
|
||||
@abc.abstractmethod
|
||||
def inspect_cpu(self, host):
|
||||
"""Inspect the CPU statistics for a host.
|
||||
|
||||
:param host: the target host
|
||||
:return: iterator of CPUStats
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def inspect_disk(self, host):
|
||||
"""Inspect the disk statistics for a host.
|
||||
|
||||
:param : the target host
|
||||
:return: iterator of tuple (Disk, DiskStats)
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def inspect_memory(self, host):
|
||||
"""Inspect the ram statistics for a host.
|
||||
|
||||
:param : the target host
|
||||
:return: iterator of MemoryStats
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def inspect_network(self, host):
|
||||
"""Inspect the network interfaces for a host.
|
||||
|
||||
:param : the target host
|
||||
:return: iterator of tuple (Interface, InterfaceStats)
|
||||
"""
|
199
ceilometer/hardware/inspector/snmp.py
Normal file
199
ceilometer/hardware/inspector/snmp.py
Normal file
@ -0,0 +1,199 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# Copyright © 2014 ZHAW SoE
|
||||
#
|
||||
# Authors: Lucas Graf <graflu0@students.zhaw.ch>
|
||||
# Toni Zehnder <zehndton@students.zhaw.ch>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Inspector for collecting data over SNMP"""
|
||||
|
||||
import urlparse
|
||||
|
||||
from ceilometer.hardware.inspector import base
|
||||
from pysnmp.entity.rfc3413.oneliner import cmdgen
|
||||
|
||||
|
||||
class SNMPException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def parse_snmp_return(ret):
|
||||
"""Check the return value of snmp operations
|
||||
|
||||
:param ret: a tuple of (errorIndication, errorStatus, errorIndex, data)
|
||||
returned by pysnmp
|
||||
:return: a tuple of (err, data)
|
||||
err: True if error found, or False if no error found
|
||||
data: a string of error description if error found, or the
|
||||
actual return data of the snmp operation
|
||||
"""
|
||||
err = True
|
||||
(errIndication, errStatus, errIdx, varBinds) = ret
|
||||
if errIndication:
|
||||
data = errIndication
|
||||
elif errStatus:
|
||||
data = "%s at %s" % (errStatus.prettyPrint(),
|
||||
errIdx and varBinds[int(errIdx) - 1] or "?")
|
||||
else:
|
||||
err = False
|
||||
data = varBinds
|
||||
return (err, data)
|
||||
|
||||
|
||||
class SNMPInspector(base.Inspector):
|
||||
#CPU OIDs
|
||||
_cpu_1_min_load_oid = "1.3.6.1.4.1.2021.10.1.3.1"
|
||||
_cpu_5_min_load_oid = "1.3.6.1.4.1.2021.10.1.3.2"
|
||||
_cpu_15_min_load_oid = "1.3.6.1.4.1.2021.10.1.3.3"
|
||||
#Memory OIDs
|
||||
_memory_total_oid = "1.3.6.1.4.1.2021.4.5.0"
|
||||
_memory_used_oid = "1.3.6.1.4.1.2021.4.6.0"
|
||||
#Disk OIDs
|
||||
_disk_index_oid = "1.3.6.1.4.1.2021.9.1.1"
|
||||
_disk_path_oid = "1.3.6.1.4.1.2021.9.1.2"
|
||||
_disk_device_oid = "1.3.6.1.4.1.2021.9.1.3"
|
||||
_disk_size_oid = "1.3.6.1.4.1.2021.9.1.6"
|
||||
_disk_used_oid = "1.3.6.1.4.1.2021.9.1.8"
|
||||
#Network Interface OIDs
|
||||
_interface_index_oid = "1.3.6.1.2.1.2.2.1.1"
|
||||
_interface_name_oid = "1.3.6.1.2.1.2.2.1.2"
|
||||
_interface_bandwidth_oid = "1.3.6.1.2.1.2.2.1.5"
|
||||
_interface_mac_oid = "1.3.6.1.2.1.2.2.1.6"
|
||||
_interface_ip_oid = "1.3.6.1.2.1.4.20.1.2"
|
||||
_interface_received_oid = "1.3.6.1.2.1.2.2.1.10"
|
||||
_interface_transmitted_oid = "1.3.6.1.2.1.2.2.1.16"
|
||||
_interface_error_oid = "1.3.6.1.2.1.2.2.1.20"
|
||||
#Default port and security name
|
||||
_port = 161
|
||||
_security_name = 'public'
|
||||
|
||||
def __init__(self):
|
||||
super(SNMPInspector, self).__init__()
|
||||
self._cmdGen = cmdgen.CommandGenerator()
|
||||
|
||||
def _get_or_walk_oid(self, oid, host, get=True):
|
||||
if get:
|
||||
func = self._cmdGen.getCmd
|
||||
ret_func = lambda x: x[0][1]
|
||||
else:
|
||||
func = self._cmdGen.nextCmd
|
||||
ret_func = lambda x: x
|
||||
ret = func(cmdgen.CommunityData(self._get_security_name(host)),
|
||||
cmdgen.UdpTransportTarget((host.hostname,
|
||||
host.port or self._port)),
|
||||
oid)
|
||||
(error, data) = parse_snmp_return(ret)
|
||||
if error:
|
||||
raise SNMPException("An error occurred, oid %(oid)s, "
|
||||
"host %(host)s, %(err)s" % dict(oid=oid,
|
||||
host=host.hostname, err=data))
|
||||
else:
|
||||
return ret_func(data)
|
||||
|
||||
def _get_value_from_oid(self, oid, host):
|
||||
return self._get_or_walk_oid(oid, host, True)
|
||||
|
||||
def _walk_oid(self, oid, host):
|
||||
return self._get_or_walk_oid(oid, host, False)
|
||||
|
||||
def inspect_cpu(self, host):
|
||||
#get 1 minute load
|
||||
cpu_1_min_load = \
|
||||
str(self._get_value_from_oid(self._cpu_1_min_load_oid, host))
|
||||
#get 5 minute load
|
||||
cpu_5_min_load = \
|
||||
str(self._get_value_from_oid(self._cpu_5_min_load_oid, host))
|
||||
#get 15 minute load
|
||||
cpu_15_min_load = \
|
||||
str(self._get_value_from_oid(self._cpu_15_min_load_oid, host))
|
||||
|
||||
yield base.CPUStats(cpu_1_min=float(cpu_1_min_load),
|
||||
cpu_5_min=float(cpu_5_min_load),
|
||||
cpu_15_min=float(cpu_15_min_load))
|
||||
|
||||
def inspect_memory(self, host):
|
||||
#get total memory
|
||||
total = self._get_value_from_oid(self._memory_total_oid, host)
|
||||
#get used memory
|
||||
used = self._get_value_from_oid(self._memory_used_oid, host)
|
||||
|
||||
yield base.MemoryStats(total=int(total), used=int(used))
|
||||
|
||||
def inspect_disk(self, host):
|
||||
disks = self._walk_oid(self._disk_index_oid, host)
|
||||
|
||||
for disk in disks:
|
||||
for object_name, value in disk:
|
||||
path_oid = "%s.%s" % (self._disk_path_oid, str(value))
|
||||
path = self._get_value_from_oid(path_oid, host)
|
||||
device_oid = "%s.%s" % (self._disk_device_oid, str(value))
|
||||
device = self._get_value_from_oid(device_oid, host)
|
||||
size_oid = "%s.%s" % (self._disk_size_oid, str(value))
|
||||
size = self._get_value_from_oid(size_oid, host)
|
||||
used_oid = "%s.%s" % (self._disk_used_oid, str(value))
|
||||
used = self._get_value_from_oid(used_oid, host)
|
||||
|
||||
disk = base.Disk(device=str(device),
|
||||
path=str(path))
|
||||
stats = base.DiskStats(size=int(size),
|
||||
used=int(used))
|
||||
|
||||
yield (disk, stats)
|
||||
|
||||
def inspect_network(self, host):
|
||||
net_interfaces = self._walk_oid(self._interface_index_oid, host)
|
||||
|
||||
for interface in net_interfaces:
|
||||
for object_name, value in interface:
|
||||
ip = self._get_ip_for_interface(host, value)
|
||||
name_oid = "%s.%s" % (self._interface_name_oid,
|
||||
str(value))
|
||||
name = self._get_value_from_oid(name_oid, host)
|
||||
mac_oid = "%s.%s" % (self._interface_mac_oid,
|
||||
str(value))
|
||||
mac = self._get_value_from_oid(mac_oid, host)
|
||||
bw_oid = "%s.%s" % (self._interface_bandwidth_oid,
|
||||
str(value))
|
||||
# bits/s to byte/s
|
||||
bandwidth = self._get_value_from_oid(bw_oid, host) / 8
|
||||
rx_oid = "%s.%s" % (self._interface_received_oid,
|
||||
str(value))
|
||||
rx_bytes = self._get_value_from_oid(rx_oid, host)
|
||||
tx_oid = "%s.%s" % (self._interface_transmitted_oid,
|
||||
str(value))
|
||||
tx_bytes = self._get_value_from_oid(tx_oid, host)
|
||||
error_oid = "%s.%s" % (self._interface_error_oid,
|
||||
str(value))
|
||||
error = self._get_value_from_oid(error_oid, host)
|
||||
|
||||
adapted_mac = mac.prettyPrint().replace('0x', '')
|
||||
interface = base.Interface(name=str(name),
|
||||
mac=adapted_mac,
|
||||
ip=str(ip))
|
||||
stats = base.InterfaceStats(bandwidth=int(bandwidth),
|
||||
rx_bytes=int(rx_bytes),
|
||||
tx_bytes=int(tx_bytes),
|
||||
error=int(error))
|
||||
yield (interface, stats)
|
||||
|
||||
def _get_security_name(self, host):
|
||||
options = urlparse.parse_qs(host.query)
|
||||
return options.get('security_name', [self._security_name])[-1]
|
||||
|
||||
def _get_ip_for_interface(self, host, interface_id):
|
||||
ip_addresses = self._walk_oid(self._interface_ip_oid, host)
|
||||
for ip in ip_addresses:
|
||||
for name, value in ip:
|
||||
if value == interface_id:
|
||||
return str(name).replace(self._interface_ip_oid + ".", "")
|
0
ceilometer/tests/hardware/__init__.py
Normal file
0
ceilometer/tests/hardware/__init__.py
Normal file
0
ceilometer/tests/hardware/inspector/__init__.py
Normal file
0
ceilometer/tests/hardware/inspector/__init__.py
Normal file
63
ceilometer/tests/hardware/inspector/base.py
Normal file
63
ceilometer/tests/hardware/inspector/base.py
Normal file
@ -0,0 +1,63 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# Copyright © 2014 Intel Corp
|
||||
#
|
||||
# Authors: Lianhao Lu <lianhao.lu@intel.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from ceilometer.hardware.inspector import base
|
||||
|
||||
|
||||
class InspectorBaseTest(object):
|
||||
"""Subclass must set self.inspector and self.host in
|
||||
self.setUp()
|
||||
"""
|
||||
|
||||
cpu = [base.CPUStats(cpu_1_min=0.1,
|
||||
cpu_5_min=0.2,
|
||||
cpu_15_min=0.3),
|
||||
]
|
||||
|
||||
network = [(base.Interface(name='eth0',
|
||||
mac='112233445566',
|
||||
ip='10.0.0.1'),
|
||||
base.InterfaceStats(bandwidth=1250000 / 8,
|
||||
rx_bytes=1000,
|
||||
tx_bytes=2000,
|
||||
error=1)),
|
||||
]
|
||||
diskspace = [(base.Disk(device='/dev/sda1', path='/'),
|
||||
base.DiskStats(size=1000, used=500),
|
||||
),
|
||||
(base.Disk(device='/dev/sda2', path='/home'),
|
||||
base.DiskStats(size=2000, used=1000),
|
||||
),
|
||||
]
|
||||
memory = [base.MemoryStats(total=1000, used=500)]
|
||||
|
||||
def test_inspect_cpu(self):
|
||||
self.assertEqual(list(self.inspector.inspect_cpu(self.host)),
|
||||
self.cpu)
|
||||
|
||||
def test_inspect_network(self):
|
||||
self.assertEqual(list(self.inspector.inspect_network(self.host)),
|
||||
self.network)
|
||||
|
||||
def test_inspect_disk(self):
|
||||
self.assertEqual(list(self.inspector.inspect_disk(self.host)),
|
||||
self.diskspace)
|
||||
|
||||
def test_inspect_memory(self):
|
||||
self.assertEqual(list(self.inspector.inspect_memory(self.host)),
|
||||
self.memory)
|
34
ceilometer/tests/hardware/inspector/test_inspector.py
Normal file
34
ceilometer/tests/hardware/inspector/test_inspector.py
Normal file
@ -0,0 +1,34 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# Copyright © 2014 Intel Corp
|
||||
#
|
||||
# Authors: Lianhao Lu <lianhao.lu@intel.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from ceilometer.hardware import inspector
|
||||
from ceilometer.openstack.common import network_utils
|
||||
from ceilometer.tests import base
|
||||
|
||||
|
||||
class TestHardwareInspector(base.BaseTestCase):
|
||||
def test_get_inspector(self):
|
||||
url = network_utils.urlsplit("snmp://")
|
||||
driver = inspector.get_inspector(url)
|
||||
self.assertTrue(driver)
|
||||
|
||||
def test_get_inspector_illegal(self):
|
||||
url = network_utils.urlsplit("illegal://")
|
||||
self.assertRaises(RuntimeError,
|
||||
inspector.get_inspector,
|
||||
url)
|
235
ceilometer/tests/hardware/inspector/test_snmp.py
Normal file
235
ceilometer/tests/hardware/inspector/test_snmp.py
Normal file
@ -0,0 +1,235 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# Copyright © 2013 Intel Corp
|
||||
#
|
||||
# Authors: Lianhao Lu <lianhao.lu@intel.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Tests for ceilometer/hardware/inspector/snmp/inspector.py
|
||||
"""
|
||||
|
||||
from ceilometer.hardware.inspector import snmp
|
||||
from ceilometer.openstack.common.fixture import mockpatch
|
||||
from ceilometer.openstack.common import network_utils
|
||||
from ceilometer.tests import base as test_base
|
||||
from ceilometer.tests.hardware.inspector import base
|
||||
|
||||
Base = base.InspectorBaseTest
|
||||
|
||||
|
||||
class FakeMac(object):
|
||||
def __init__(self):
|
||||
self.val = "0x%s" % Base.network[0][0].mac
|
||||
|
||||
def prettyPrint(self):
|
||||
return str(self.val)
|
||||
|
||||
ins = snmp.SNMPInspector
|
||||
GETCMD_MAP = {
|
||||
ins._cpu_1_min_load_oid: (None,
|
||||
None,
|
||||
0,
|
||||
[('',
|
||||
Base.cpu[0].cpu_1_min,
|
||||
)],
|
||||
),
|
||||
ins._cpu_5_min_load_oid: (None,
|
||||
None,
|
||||
0,
|
||||
[('',
|
||||
Base.cpu[0].cpu_5_min,
|
||||
)],
|
||||
),
|
||||
ins._cpu_15_min_load_oid: (None,
|
||||
None,
|
||||
0,
|
||||
[('',
|
||||
Base.cpu[0].cpu_15_min,
|
||||
)],
|
||||
),
|
||||
ins._memory_total_oid: (None,
|
||||
None,
|
||||
0,
|
||||
[('',
|
||||
Base.memory[0].total,
|
||||
)],
|
||||
),
|
||||
ins._memory_used_oid: (None,
|
||||
None,
|
||||
0,
|
||||
[('',
|
||||
Base.memory[0].used,
|
||||
)],
|
||||
),
|
||||
ins._disk_path_oid + '.1': (None,
|
||||
None,
|
||||
0,
|
||||
[('',
|
||||
Base.diskspace[0][0].path,
|
||||
)],
|
||||
),
|
||||
ins._disk_device_oid + '.1': (None,
|
||||
None,
|
||||
0,
|
||||
[('',
|
||||
Base.diskspace[0][0].device,
|
||||
)],
|
||||
),
|
||||
ins._disk_size_oid + '.1': (None,
|
||||
None,
|
||||
0,
|
||||
[('',
|
||||
Base.diskspace[0][1].size,
|
||||
)],
|
||||
),
|
||||
ins._disk_used_oid + '.1': (None,
|
||||
None,
|
||||
0,
|
||||
[('',
|
||||
Base.diskspace[0][1].used,
|
||||
)],
|
||||
),
|
||||
ins._disk_path_oid + '.2': (None,
|
||||
None,
|
||||
0,
|
||||
[('',
|
||||
Base.diskspace[1][0].path,
|
||||
)],
|
||||
),
|
||||
ins._disk_device_oid + '.2': (None,
|
||||
None,
|
||||
0,
|
||||
[('',
|
||||
Base.diskspace[1][0].device,
|
||||
)],
|
||||
),
|
||||
ins._disk_size_oid + '.2': (None,
|
||||
None,
|
||||
0,
|
||||
[('',
|
||||
Base.diskspace[1][1].size,
|
||||
)],
|
||||
),
|
||||
ins._disk_used_oid + '.2': (None,
|
||||
None,
|
||||
0,
|
||||
[('',
|
||||
Base.diskspace[1][1].used,
|
||||
)],
|
||||
),
|
||||
ins._interface_name_oid + '.1': (None,
|
||||
None,
|
||||
0,
|
||||
[('',
|
||||
Base.network[0][0].name,
|
||||
)],
|
||||
),
|
||||
ins._interface_mac_oid + '.1': (None,
|
||||
None,
|
||||
0,
|
||||
[('',
|
||||
FakeMac(),
|
||||
)],
|
||||
),
|
||||
ins._interface_bandwidth_oid + '.1': (None,
|
||||
None,
|
||||
0,
|
||||
[('',
|
||||
Base.network[0][1].bandwidth * 8,
|
||||
)],
|
||||
),
|
||||
ins._interface_received_oid + '.1': (None,
|
||||
None,
|
||||
0,
|
||||
[('',
|
||||
Base.network[0][1].rx_bytes,
|
||||
)],
|
||||
),
|
||||
ins._interface_transmitted_oid + '.1': (None,
|
||||
None,
|
||||
0,
|
||||
[('',
|
||||
Base.network[0][1].tx_bytes,
|
||||
)],
|
||||
),
|
||||
ins._interface_error_oid + '.1': (None,
|
||||
None,
|
||||
0,
|
||||
[('',
|
||||
Base.network[0][1].error,
|
||||
)],
|
||||
),
|
||||
}
|
||||
|
||||
NEXTCMD_MAP = {
|
||||
ins._disk_index_oid: (None,
|
||||
None,
|
||||
0,
|
||||
[[('1.3.6.1.4.1.2021.9.1.1.1', 1)],
|
||||
[('1.3.6.1.4.1.2021.9.1.1.2', 2)]]),
|
||||
ins._interface_index_oid: (None,
|
||||
None,
|
||||
0,
|
||||
[[('1.3.6.1.2.1.2.2.1.1.1', 1)],
|
||||
]),
|
||||
ins._interface_ip_oid: (None,
|
||||
None,
|
||||
0,
|
||||
[[('1.3.6.1.2.1.4.20.1.2.10.0.0.1',
|
||||
1)],
|
||||
]),
|
||||
}
|
||||
|
||||
|
||||
def faux_getCmd(authData, transportTarget, oid):
|
||||
try:
|
||||
return GETCMD_MAP[oid]
|
||||
except KeyError:
|
||||
return ("faux_getCmd Error", None, 0, [])
|
||||
|
||||
|
||||
def faux_nextCmd(authData, transportTarget, oid):
|
||||
try:
|
||||
return NEXTCMD_MAP[oid]
|
||||
except KeyError:
|
||||
return ("faux_nextCmd Error", None, 0, [])
|
||||
|
||||
|
||||
class TestSNMPInspector(Base, test_base.BaseTestCase):
|
||||
def setUp(self):
|
||||
super(TestSNMPInspector, self).setUp()
|
||||
self.inspector = snmp.SNMPInspector()
|
||||
self.host = network_utils.urlsplit("snmp://localhost")
|
||||
self.useFixture(mockpatch.PatchObject(
|
||||
self.inspector._cmdGen, 'getCmd', new=faux_getCmd))
|
||||
self.useFixture(mockpatch.PatchObject(
|
||||
self.inspector._cmdGen, 'nextCmd', new=faux_nextCmd))
|
||||
|
||||
def test_get_security_name(self):
|
||||
self.assertEqual(self.inspector._get_security_name(self.host),
|
||||
self.inspector._security_name)
|
||||
host2 = network_utils.urlsplit("snmp://foo:80?security_name=fake")
|
||||
self.assertEqual(self.inspector._get_security_name(host2),
|
||||
'fake')
|
||||
|
||||
def test_get_cmd_error(self):
|
||||
self.useFixture(mockpatch.PatchObject(
|
||||
self.inspector, '_memory_total_oid', new='failure'))
|
||||
|
||||
def get_list(func, *args, **kwargs):
|
||||
return list(func(*args, **kwargs))
|
||||
|
||||
self.assertRaises(snmp.SNMPException,
|
||||
get_list,
|
||||
self.inspector.inspect_memory,
|
||||
self.host)
|
@ -16,6 +16,7 @@ oslo.config>=1.2.0
|
||||
pbr>=0.6,<1.0
|
||||
pecan>=0.4.5
|
||||
pymongo>=2.4
|
||||
pysnmp>=4.2.1,<5.0.0
|
||||
python-ceilometerclient>=1.0.6
|
||||
python-glanceclient>=0.9.0
|
||||
python-keystoneclient>=0.6.0
|
||||
|
@ -126,6 +126,9 @@ ceilometer.compute.virt =
|
||||
libvirt = ceilometer.compute.virt.libvirt.inspector:LibvirtInspector
|
||||
hyperv = ceilometer.compute.virt.hyperv.inspector:HyperVInspector
|
||||
|
||||
ceilometer.hardware.inspectors =
|
||||
snmp = ceilometer.hardware.inspector.snmp:SNMPInspector
|
||||
|
||||
ceilometer.transformer =
|
||||
accumulator = ceilometer.transformer.accumulator:TransformerAccumulator
|
||||
unit_conversion = ceilometer.transformer.conversions:ScalingTransformer
|
||||
|
Loading…
x
Reference in New Issue
Block a user