Commit 7cff2158 authored by Jenkins's avatar Jenkins Committed by Gerrit Code Review

Merge "Enable the Load Balancer v2 for the Ceilometer(Part Two)"

parents 4775c1c1 e7a3d62f
......@@ -52,6 +52,24 @@ class LBMembersDiscovery(_BaseServicesDiscovery):
if i.get('status', None) != 'error']
class LBListenersDiscovery(_BaseServicesDiscovery):
def discover(self, manager, param=None):
"""Discover load balancer listener resources to monitor."""
listeners = self.neutron_cli.list_listener()
return [i for i in listeners
if i.get('operating_status', None) != 'error']
class LBLoadBalancersDiscovery(_BaseServicesDiscovery):
def discover(self, manager, param=None):
"""Discover load balancer resources to monitor."""
loadbalancers = self.neutron_cli.list_loadbalancer()
return [i for i in loadbalancers
if i.get('operating_status', None) != 'error']
class LBHealthMonitorsDiscovery(_BaseServicesDiscovery):
def discover(self, manager, param=None):
"""Discover resources to monitor."""
......
......@@ -233,6 +233,7 @@ class _LBStatsPollster(base.BaseServicesPollster):
def __init__(self):
super(_LBStatsPollster, self).__init__()
self.client = neutron_client.Client()
self.lb_version = cfg.CONF.service_types.neutron_lbaas_version
@staticmethod
def make_sample_from_pool(pool, name, type, unit, volume,
......@@ -263,22 +264,49 @@ class _LBStatsPollster(base.BaseServicesPollster):
)
return i_cache[pool_id]
def _populate_stats_cache_v2(self, loadbalancer_id, cache):
i_cache = cache.setdefault("lbstats", {})
if loadbalancer_id not in i_cache:
stats = self.client.get_loadbalancer_stats(loadbalancer_id)
i_cache[loadbalancer_id] = LBStatsData(
active_connections=stats['active_connections'],
total_connections=stats['total_connections'],
bytes_in=stats['bytes_in'],
bytes_out=stats['bytes_out'],
)
return i_cache[loadbalancer_id]
@property
def default_discovery(self):
return 'lb_pools'
discovery_resource = 'lb_pools'
if self.lb_version == 'v2':
discovery_resource = 'lb_loadbalancers'
return discovery_resource
@abc.abstractmethod
def _get_sample(pool, c_data):
"""Return one Sample."""
def get_samples(self, manager, cache, resources):
for pool in resources:
try:
c_data = self._populate_stats_cache(pool['id'], cache)
yield self._get_sample(pool, c_data)
except Exception as err:
LOG.exception(_('Ignoring pool %(pool_id)s: %(error)s'),
{'pool_id': pool['id'], 'error': err})
if self.lb_version == 'v1':
for pool in resources:
try:
c_data = self._populate_stats_cache(pool['id'], cache)
yield self._get_sample(pool, c_data)
except Exception:
LOG.exception(_('Ignoring pool %(pool_id)s'),
{'pool_id': pool['id']})
elif self.lb_version == 'v2':
for loadbalancer in resources:
try:
c_data = self._populate_stats_cache_v2(loadbalancer['id'],
cache)
yield self._get_sample(loadbalancer, c_data)
except Exception:
LOG.exception(
_('Ignoring '
'loadbalancer %(loadbalancer_id)s'),
{'loadbalancer_id': loadbalancer['id']})
class LBActiveConnectionsPollster(_LBStatsPollster):
......@@ -352,3 +380,94 @@ def make_sample_from_pool(pool, name, type, unit, volume,
timestamp=timeutils.utcnow().isoformat(),
resource_metadata=resource_metadata,
)
class LBListenerPollster(BaseLBPollster):
"""Pollster to capture Load Balancer Listener status samples."""
FIELDS = ['admin_state_up',
'connection_limit',
'description',
'name',
'default_pool_id',
'protocol',
'protocol_port',
'operating_status',
'loadbalancers'
]
@property
def default_discovery(self):
return 'lb_listeners'
def get_samples(self, manager, cache, resources):
resources = resources or []
for listener in resources:
LOG.debug("Load Balancer Listener : %s" % listener)
status = self.get_load_balancer_status_id(
listener['operating_status'])
if status == -1:
# unknown status, skip this sample
LOG.warning(_("Unknown status %(stat)s received on listener "
"%(id)s, skipping sample")
% {'stat': listener['operating_status'],
'id': listener['id']})
continue
yield sample.Sample(
name='network.services.lb.listener',
type=sample.TYPE_GAUGE,
unit='listener',
volume=status,
user_id=None,
project_id=listener['tenant_id'],
resource_id=listener['id'],
timestamp=timeutils.utcnow().isoformat(),
resource_metadata=self.extract_metadata(listener)
)
class LBLoadBalancerPollster(BaseLBPollster):
"""Pollster to capture Load Balancer status samples."""
FIELDS = ['admin_state_up',
'description',
'vip_address',
'listeners',
'name',
'vip_subnet_id',
'operating_status',
]
@property
def default_discovery(self):
return 'lb_loadbalancers'
def get_samples(self, manager, cache, resources):
resources = resources or []
for loadbalancer in resources:
LOG.debug("Load Balancer: %s" % loadbalancer)
status = self.get_load_balancer_status_id(
loadbalancer['operating_status'])
if status == -1:
# unknown status, skip this sample
LOG.warning(_("Unknown status %(stat)s received "
"on Load Balancer "
"%(id)s, skipping sample")
% {'stat': loadbalancer['operating_status'],
'id': loadbalancer['id']})
continue
yield sample.Sample(
name='network.services.lb.loadbalancer',
type=sample.TYPE_GAUGE,
unit='loadbalancer',
volume=status,
user_id=None,
project_id=loadbalancer['tenant_id'],
resource_id=loadbalancer['id'],
timestamp=timeutils.utcnow().isoformat(),
resource_metadata=self.extract_metadata(loadbalancer)
)
......@@ -385,3 +385,28 @@ class Client(object):
break
return status_dict
def list_listener(self):
"""This method is used to get the list of the listeners."""
resp = self.client.list_listeners()
resources = resp.get('listeners')
for listener in resources:
loadbalancer_id = listener.get('loadbalancers')[0].get('id')
status = self._get_listener_status(loadbalancer_id)
listener['operating_status'] = status[listener.get('id')]
return resources
def list_loadbalancer(self):
"""This method is used to get the list of the loadbalancers."""
resp = self.client.list_loadbalancers()
resources = resp.get('loadbalancers')
return resources
def get_loadbalancer_stats(self, loadbalancer_id):
"""This method is used to get the statistics of the loadbalancer.
:param loadbalancer_id: the ID of the specified loadbalancer
"""
resp = self.client.retrieve_loadbalancer_stats(loadbalancer_id)
resource = resp.get('stats')
return resource
......@@ -474,7 +474,6 @@ class TestLBStatsPollster(_BaseTestLBPollster):
def _check_get_samples(self, factory, sample_name, expected_volume,
expected_type):
pollster = factory()
cache = {}
samples = list(pollster.get_samples(self.manager, cache,
self.fake_get_pools()))
......
This diff is collapsed.
......@@ -197,6 +197,24 @@ class TestNeutronClientLBaaSV2(base.BaseTestCase):
}
}
@staticmethod
def fake_list_lbaas_listeners():
return {
'listeners': [{
'default_pool_id': None,
'protocol': 'HTTP',
'description': '',
'admin_state_up': True,
'loadbalancers': [{
'id': 'a9729389-6147-41a3-ab22-a24aed8692b2'
}],
'tenant_id': '3e4d8bec50a845fcb09e03a4375c691d',
'connection_limit': 100,
'protocol_port': 80,
'id': '35cb8516-1173-4035-8dae-0dae3453f37f',
'name': 'listener_one'
}]}
@mock.patch.object(client.Client,
'list_lbaas_pools')
@mock.patch.object(client.Client,
......@@ -300,3 +318,19 @@ class TestNeutronClientLBaaSV2(base.BaseTestCase):
for key in result_status.keys():
self.assertIn(key, expected_keys)
self.assertEqual(excepted_status[key], result_status[key])
@mock.patch.object(client.Client,
'list_listeners')
@mock.patch.object(neutron_client.Client,
'_retrieve_loadbalancer_status_tree')
def test_list_listener(self, mock_status, mock_list_listeners):
mock_list_listeners.return_value = (
self.fake_list_lbaas_listeners())
mock_status.return_value = (
self.fake_retrieve_loadbalancer_status())
listeners = self.nc.list_listener()
expected_key = '35cb8516-1173-4035-8dae-0dae3453f37f'
expected_status = 'ONLINE'
self.assertEqual(1, len(listeners))
self.assertEqual(expected_key, listeners[0]['id'])
self.assertEqual(expected_status, listeners[0]['operating_status'])
......@@ -64,6 +64,8 @@ ceilometer.discover =
lb_pools = ceilometer.network.services.discovery:LBPoolsDiscovery
lb_vips = ceilometer.network.services.discovery:LBVipsDiscovery
lb_members = ceilometer.network.services.discovery:LBMembersDiscovery
lb_listeners = ceilometer.network.services.discovery:LBListenersDiscovery
lb_loadbalancers = ceilometer.network.services.discovery:LBLoadBalancersDiscovery
lb_health_probes = ceilometer.network.services.discovery:LBHealthMonitorsDiscovery
vpn_services = ceilometer.network.services.discovery:VPNServicesDiscovery
ipsec_connections = ceilometer.network.services.discovery:IPSecConnectionsDiscovery
......@@ -167,6 +169,8 @@ ceilometer.poll.central =
network.services.lb.pool = ceilometer.network.services.lbaas:LBPoolPollster
network.services.lb.vip = ceilometer.network.services.lbaas:LBVipPollster
network.services.lb.member = ceilometer.network.services.lbaas:LBMemberPollster
network.services.lb.listener = ceilometer.network.services.lbaas:LBListenerPollster
network.services.lb.loadbalancer = ceilometer.network.services.lbaas:LBLoadBalancerPollster
network.services.lb.health_monitor = ceilometer.network.services.lbaas:LBHealthMonitorPollster
network.services.lb.total.connections = ceilometer.network.services.lbaas:LBTotalConnectionsPollster
network.services.lb.active.connections = ceilometer.network.services.lbaas:LBActiveConnectionsPollster
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment