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:
parent
46ed284887
commit
1cfc3d067c
|
@ -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']
|
|
@ -36,7 +36,8 @@ CONF.import_opt('default_timeout',
|
||||||
|
|
||||||
COE_CLASS_PATH = {
|
COE_CLASS_PATH = {
|
||||||
bay_type.SWARM: 'magnum.conductor.swarm_monitor.SwarmMonitor',
|
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])
|
coe_cls = importutils.import_class(COE_CLASS_PATH[baymodel.coe])
|
||||||
return coe_cls(context, bay)
|
return coe_cls(context, bay)
|
||||||
|
|
||||||
# TODO(hongbin): add support for other bay types
|
|
||||||
LOG.debug("Cannot create monitor with bay type '%s'" % baymodel.coe)
|
LOG.debug("Cannot create monitor with bay type '%s'" % baymodel.coe)
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -15,7 +15,10 @@
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
|
from oslo_serialization import jsonutils
|
||||||
|
|
||||||
from magnum.conductor import k8s_monitor
|
from magnum.conductor import k8s_monitor
|
||||||
|
from magnum.conductor import mesos_monitor
|
||||||
from magnum.conductor import monitors
|
from magnum.conductor import monitors
|
||||||
from magnum.conductor import swarm_monitor
|
from magnum.conductor import swarm_monitor
|
||||||
from magnum import objects
|
from magnum import objects
|
||||||
|
@ -44,6 +47,8 @@ class MonitorsTestCase(base.TestCase):
|
||||||
self.bay = objects.Bay(self.context, **bay)
|
self.bay = objects.Bay(self.context, **bay)
|
||||||
self.monitor = swarm_monitor.SwarmMonitor(self.context, self.bay)
|
self.monitor = swarm_monitor.SwarmMonitor(self.context, self.bay)
|
||||||
self.k8s_monitor = k8s_monitor.K8sMonitor(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.'
|
p = mock.patch('magnum.conductor.swarm_monitor.SwarmMonitor.'
|
||||||
'metrics_spec', new_callable=mock.PropertyMock)
|
'metrics_spec', new_callable=mock.PropertyMock)
|
||||||
self.mock_metrics_spec = p.start()
|
self.mock_metrics_spec = p.start()
|
||||||
|
@ -66,6 +71,14 @@ class MonitorsTestCase(base.TestCase):
|
||||||
monitor = monitors.create_monitor(self.context, self.bay)
|
monitor = monitors.create_monitor(self.context, self.bay)
|
||||||
self.assertIsInstance(monitor, k8s_monitor.K8sMonitor)
|
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')
|
@mock.patch('magnum.objects.BayModel.get_by_uuid')
|
||||||
def test_create_monitor_unsupported_coe(self, mock_baymodel_get_by_uuid):
|
def test_create_monitor_unsupported_coe(self, mock_baymodel_get_by_uuid):
|
||||||
baymodel = mock.MagicMock()
|
baymodel = mock.MagicMock()
|
||||||
|
@ -216,3 +229,58 @@ class MonitorsTestCase(base.TestCase):
|
||||||
self.k8s_monitor.data = test_data
|
self.k8s_monitor.data = test_data
|
||||||
mem_util = self.k8s_monitor.compute_memory_util()
|
mem_util = self.k8s_monitor.compute_memory_util()
|
||||||
self.assertEqual(0, mem_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)
|
||||||
|
|
Loading…
Reference in New Issue