diff --git a/ceilometer/hardware/discovery.py b/ceilometer/hardware/discovery.py new file mode 100644 index 000000000..643830879 --- /dev/null +++ b/ceilometer/hardware/discovery.py @@ -0,0 +1,62 @@ +# -*- encoding: utf-8 -*- +# +# 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 oslo.config import cfg + +from ceilometer import nova_client +from ceilometer.openstack.common.gettextutils import _ +from ceilometer.openstack.common import log +from ceilometer import plugin + + +LOG = log.getLogger(__name__) + +OPTS = [ + cfg.StrOpt('url_scheme', + default='snmp://', + help='URL scheme to use for hardware nodes'), + cfg.StrOpt('readonly_user_name', + default='ro_snmp_user', + help='SNMPd user name of all nodes running in the cloud.'), + cfg.StrOpt('readonly_user_password', + default='password', + help='SNMPd password of all the nodes running in the cloud'), +] +cfg.CONF.register_opts(OPTS, group='hardware') + + +class NodesDiscoveryTripleO(plugin.DiscoveryBase): + def __init__(self): + super(NodesDiscoveryTripleO, self).__init__() + self.nova_cli = nova_client.Client() + + def discover(self, param=None): + """Discover resources to monitor.""" + + instances = self.nova_cli.instance_get_all() + ip_addresses = [] + for instance in instances: + try: + ip_address = instance.addresses['ctlplane'][0]['addr'] + final_address = ( + cfg.CONF.hardware.url_scheme + + cfg.CONF.hardware.readonly_user_name + ':' + + cfg.CONF.hardware.readonly_user_password + '@' + + ip_address) + ip_addresses.append(final_address) + except KeyError: + LOG.error(_("Couldn't obtain IP address of" + "instance %s") % instance.id) + + return ip_addresses diff --git a/ceilometer/hardware/inspector/snmp.py b/ceilometer/hardware/inspector/snmp.py index f32503d98..84d712173 100644 --- a/ceilometer/hardware/inspector/snmp.py +++ b/ceilometer/hardware/inspector/snmp.py @@ -18,7 +18,6 @@ """Inspector for collecting data over SNMP""" from pysnmp.entity.rfc3413.oneliner import cmdgen -from six.moves.urllib import parse as urlparse from ceilometer.hardware.inspector import base @@ -73,9 +72,8 @@ class SNMPInspector(base.Inspector): _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 + # Default port _port = 161 - _security_name = 'public' def __init__(self): super(SNMPInspector, self).__init__() @@ -88,7 +86,8 @@ class SNMPInspector(base.Inspector): else: func = self._cmdGen.nextCmd ret_func = lambda x: x - ret = func(cmdgen.CommunityData(self._get_security_name(host)), + + ret = func(self._get_auth_strategy(host), cmdgen.UdpTransportTarget((host.hostname, host.port or self._port)), oid) @@ -100,6 +99,15 @@ class SNMPInspector(base.Inspector): else: return ret_func(data) + def _get_auth_strategy(self, host): + if host.password: + auth_strategy = cmdgen.UsmUserData(host.username, + authKey=host.password) + else: + auth_strategy = cmdgen.CommunityData(host.username or 'public') + + return auth_strategy + def _get_value_from_oid(self, oid, host): return self._get_or_walk_oid(oid, host, True) @@ -186,10 +194,6 @@ class SNMPInspector(base.Inspector): 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: diff --git a/ceilometer/nova_client.py b/ceilometer/nova_client.py index cd5b68895..8b7989222 100644 --- a/ceilometer/nova_client.py +++ b/ceilometer/nova_client.py @@ -131,6 +131,14 @@ class Client(object): detailed=True, search_opts=search_opts)) + @logged + def instance_get_all(self): + """Returns list of all instances.""" + search_opts = {'all_tenants': True} + return self.nova_client.servers.list( + detailed=True, + search_opts=search_opts) + @logged def floating_ip_get_all(self): """Returns all floating ips.""" diff --git a/ceilometer/tests/hardware/inspector/test_snmp.py b/ceilometer/tests/hardware/inspector/test_snmp.py index 95be7ca5a..4c8568b0a 100644 --- a/ceilometer/tests/hardware/inspector/test_snmp.py +++ b/ceilometer/tests/hardware/inspector/test_snmp.py @@ -214,13 +214,6 @@ class TestSNMPInspector(Base, test_base.BaseTestCase): 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')) diff --git a/ceilometer/tests/test_novaclient.py b/ceilometer/tests/test_novaclient.py index 3606baffe..9575e9249 100644 --- a/ceilometer/tests/test_novaclient.py +++ b/ceilometer/tests/test_novaclient.py @@ -96,6 +96,16 @@ class TestNovaClient(test.BaseTestCase): self.assertEqual(11, instances[0].kernel_id) self.assertEqual(21, instances[0].ramdisk_id) + def test_instance_get_all(self): + with mock.patch.object(self.nv.nova_client.servers, 'list', + side_effect=self.fake_servers_list): + instances = self.nv.instance_get_all() + + self.assertEqual(2, len(instances)) + self.assertEqual(42, instances[0].id) + self.assertEqual(1, instances[0].flavor['id']) + self.assertEqual(1, instances[0].image['id']) + @staticmethod def fake_servers_list_unknown_flavor(*args, **kwargs): a = mock.MagicMock() diff --git a/setup.cfg b/setup.cfg index 3cdf6fc7e..acae8a376 100644 --- a/setup.cfg +++ b/setup.cfg @@ -81,6 +81,7 @@ ceilometer.discover = ipsec_connections = ceilometer.network.services.discovery:IPSecConnectionsDiscovery fw_services = ceilometer.network.services.discovery:FirewallDiscovery fw_policy = ceilometer.network.services.discovery:FirewallPolicyDiscovery + tripleo_overcloud_nodes = ceilometer.hardware.discovery:NodesDiscoveryTripleO ceilometer.poll.compute = disk.read.requests = ceilometer.compute.pollsters.disk:ReadRequestsPollster