Monitor driver for mesos bay type

Add support for computing memory utilization of memory bay

Change-Id: Iadb710f030fca62f4edb42a02209de81e369ce88
Closes-Bug: #1500300
This commit is contained in:
Bharath Thiruveedula 2015-11-12 23:06:21 +05:30
parent 46ed284887
commit 1cfc3d067c
3 changed files with 122 additions and 2 deletions

View File

@ -0,0 +1,52 @@
# 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_serialization import jsonutils
from magnum.common import urlfetch
from magnum.conductor.monitors import MonitorBase
class MesosMonitor(MonitorBase):
def __init__(self, context, bay):
super(MesosMonitor, self).__init__(context, bay)
self.data = {}
@property
def metrics_spec(self):
return {
'memory_util': {
'unit': '%',
'func': 'compute_memory_util',
},
}
def _build_url(self, url, protocol='http', port='80', path='/'):
return protocol + '://' + url + ':' + port + path
def pull_data(self):
mesos_master_url = self._build_url(self.bay.api_address,
port='5050',
path='/state')
state_json = jsonutils.loads(urlfetch.get(mesos_master_url))
self.data['mem_total'] = 0
self.data['mem_used'] = 0
for slave in state_json['slaves']:
self.data['mem_total'] += slave['resources']['mem']
self.data['mem_used'] += slave['used_resources']['mem']
def compute_memory_util(self):
if self.data['mem_total'] == 0:
return 0
else:
return self.data['mem_used'] * 100 / self.data['mem_total']

View File

@ -36,7 +36,8 @@ CONF.import_opt('default_timeout',
COE_CLASS_PATH = {
bay_type.SWARM: 'magnum.conductor.swarm_monitor.SwarmMonitor',
bay_type.KUBERNETES: 'magnum.conductor.k8s_monitor.K8sMonitor'
bay_type.KUBERNETES: 'magnum.conductor.k8s_monitor.K8sMonitor',
bay_type.MESOS: 'magnum.conductor.mesos_monitor.MesosMonitor'
}
@ -73,6 +74,5 @@ def create_monitor(context, bay):
coe_cls = importutils.import_class(COE_CLASS_PATH[baymodel.coe])
return coe_cls(context, bay)
# TODO(hongbin): add support for other bay types
LOG.debug("Cannot create monitor with bay type '%s'" % baymodel.coe)
return None

View File

@ -15,7 +15,10 @@
import mock
from oslo_serialization import jsonutils
from magnum.conductor import k8s_monitor
from magnum.conductor import mesos_monitor
from magnum.conductor import monitors
from magnum.conductor import swarm_monitor
from magnum import objects
@ -44,6 +47,8 @@ class MonitorsTestCase(base.TestCase):
self.bay = objects.Bay(self.context, **bay)
self.monitor = swarm_monitor.SwarmMonitor(self.context, self.bay)
self.k8s_monitor = k8s_monitor.K8sMonitor(self.context, self.bay)
self.mesos_monitor = mesos_monitor.MesosMonitor(self.context,
self.bay)
p = mock.patch('magnum.conductor.swarm_monitor.SwarmMonitor.'
'metrics_spec', new_callable=mock.PropertyMock)
self.mock_metrics_spec = p.start()
@ -66,6 +71,14 @@ class MonitorsTestCase(base.TestCase):
monitor = monitors.create_monitor(self.context, self.bay)
self.assertIsInstance(monitor, k8s_monitor.K8sMonitor)
@mock.patch('magnum.objects.BayModel.get_by_uuid')
def test_create_monitor_mesos_bay(self, mock_baymodel_get_by_uuid):
baymodel = mock.MagicMock()
baymodel.coe = 'mesos'
mock_baymodel_get_by_uuid.return_value = baymodel
monitor = monitors.create_monitor(self.context, self.bay)
self.assertIsInstance(monitor, mesos_monitor.MesosMonitor)
@mock.patch('magnum.objects.BayModel.get_by_uuid')
def test_create_monitor_unsupported_coe(self, mock_baymodel_get_by_uuid):
baymodel = mock.MagicMock()
@ -216,3 +229,58 @@ class MonitorsTestCase(base.TestCase):
self.k8s_monitor.data = test_data
mem_util = self.k8s_monitor.compute_memory_util()
self.assertEqual(0, mem_util)
@mock.patch('magnum.common.urlfetch.get')
def test_mesos_monitor_pull_data_success(self, mock_url_get):
state_json = {
'slaves': [{
'resources': {
'mem': 100
},
'used_resources': {
'mem': 50
}
}]
}
state_json = jsonutils.dumps(state_json)
mock_url_get.return_value = state_json
self.mesos_monitor.pull_data()
self.assertEqual(self.mesos_monitor.data['mem_total'],
100)
self.assertEqual(self.mesos_monitor.data['mem_used'],
50)
def test_mesos_monitor_get_metric_names(self):
mesos_metric_spec = 'magnum.conductor.mesos_monitor.MesosMonitor.'\
'metrics_spec'
with mock.patch(mesos_metric_spec,
new_callable=mock.PropertyMock) as mock_mesos_metric:
mock_mesos_metric.return_value = self.test_metrics_spec
names = self.mesos_monitor.get_metric_names()
self.assertEqual(sorted(['metric1', 'metric2']), sorted(names))
def test_mesos_monitor_get_metric_unit(self):
mesos_metric_spec = 'magnum.conductor.mesos_monitor.MesosMonitor.' \
'metrics_spec'
with mock.patch(mesos_metric_spec,
new_callable=mock.PropertyMock) as mock_mesos_metric:
mock_mesos_metric.return_value = self.test_metrics_spec
unit = self.mesos_monitor.get_metric_unit('metric1')
self.assertEqual('metric1_unit', unit)
def test_mesos_monitor_compute_memory_util(self):
test_data = {
'mem_total': 100,
'mem_used': 50
}
self.mesos_monitor.data = test_data
mem_util = self.mesos_monitor.compute_memory_util()
self.assertEqual(50, mem_util)
test_data = {
'mem_total': 0,
'pods': 0,
}
self.mesos_monitor.data = test_data
mem_util = self.mesos_monitor.compute_memory_util()
self.assertEqual(0, mem_util)