Merge "Move scale managers at driver level"
This commit is contained in:
commit
06b97cc7d7
@ -13,11 +13,10 @@
|
||||
# under the License.
|
||||
|
||||
import abc
|
||||
from marathon import MarathonClient
|
||||
from oslo_log import log as logging
|
||||
|
||||
from magnum.common import exception
|
||||
from magnum.conductor import k8s_api as k8s
|
||||
from magnum.drivers.common.driver import Driver
|
||||
from magnum.i18n import _
|
||||
from magnum.i18n import _LI
|
||||
from magnum.i18n import _LW
|
||||
@ -28,13 +27,9 @@ LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_scale_manager(context, osclient, cluster):
|
||||
manager = None
|
||||
coe = cluster.cluster_template.coe
|
||||
if coe == 'kubernetes':
|
||||
manager = K8sScaleManager(context, osclient, cluster)
|
||||
elif coe == 'mesos':
|
||||
manager = MesosScaleManager(context, osclient, cluster)
|
||||
else:
|
||||
cluster_driver = Driver.get_driver_for_cluster(context, cluster)
|
||||
manager = cluster_driver.get_scale_manager(context, osclient, cluster)
|
||||
if not manager:
|
||||
LOG.warning(_LW(
|
||||
"Currently only kubernetes and mesos cluster scale manager "
|
||||
"are available"))
|
||||
@ -94,41 +89,3 @@ class ScaleManager(object):
|
||||
def _get_hosts_with_container(self, context, cluster):
|
||||
"""Return the hosts with container running on them."""
|
||||
pass
|
||||
|
||||
|
||||
class K8sScaleManager(ScaleManager):
|
||||
|
||||
def __init__(self, context, osclient, cluster):
|
||||
super(K8sScaleManager, self).__init__(context, osclient, cluster)
|
||||
|
||||
def _get_hosts_with_container(self, context, cluster):
|
||||
k8s_api = k8s.create_k8s_api(self.context, cluster)
|
||||
hosts = set()
|
||||
for pod in k8s_api.list_namespaced_pod(namespace='default').items:
|
||||
hosts.add(pod.spec.node_name)
|
||||
|
||||
return hosts
|
||||
|
||||
|
||||
class MesosScaleManager(ScaleManager):
|
||||
"""When scaling a mesos cluster, MesosScaleManager will inspect the
|
||||
|
||||
nodes and find out those with containers on them. Thus we can
|
||||
ask Heat to delete the nodes without containers. Note that this
|
||||
is a best effort basis -- Magnum doesn't have any synchronization
|
||||
with Marathon, so while Magnum is checking for the containers to
|
||||
choose nodes to remove, new containers can be deployed on the
|
||||
nodes to be removed.
|
||||
"""
|
||||
|
||||
def __init__(self, context, osclient, cluster):
|
||||
super(MesosScaleManager, self).__init__(context, osclient, cluster)
|
||||
|
||||
def _get_hosts_with_container(self, context, cluster):
|
||||
marathon_client = MarathonClient(
|
||||
'http://' + cluster.api_address + ':8080')
|
||||
hosts = set()
|
||||
for task in marathon_client.list_tasks():
|
||||
hosts.add(task.host)
|
||||
|
||||
return hosts
|
||||
|
@ -179,3 +179,8 @@ class Driver(object):
|
||||
"""return the monitor with container data for this driver."""
|
||||
|
||||
return None
|
||||
|
||||
def get_scale_manager(self, context, osclient, cluster):
|
||||
"""return the scale manager for this driver."""
|
||||
|
||||
return None
|
||||
|
33
magnum/drivers/common/k8s_scale_manager.py
Normal file
33
magnum/drivers/common/k8s_scale_manager.py
Normal file
@ -0,0 +1,33 @@
|
||||
# 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_log import log as logging
|
||||
|
||||
from magnum.conductor import k8s_api as k8s
|
||||
from magnum.conductor.scale_manager import ScaleManager
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class K8sScaleManager(ScaleManager):
|
||||
|
||||
def __init__(self, context, osclient, cluster):
|
||||
super(K8sScaleManager, self).__init__(context, osclient, cluster)
|
||||
|
||||
def _get_hosts_with_container(self, context, cluster):
|
||||
k8s_api = k8s.create_k8s_api(self.context, cluster)
|
||||
hosts = set()
|
||||
for pod in k8s_api.list_namespaced_pod(namespace='default').items:
|
||||
hosts.add(pod.spec.node_name)
|
||||
|
||||
return hosts
|
@ -13,6 +13,7 @@
|
||||
# under the License.
|
||||
|
||||
from magnum.drivers.common import k8s_monitor
|
||||
from magnum.drivers.common.k8s_scale_manager import K8sScaleManager
|
||||
from magnum.drivers.heat import driver
|
||||
from magnum.drivers.k8s_coreos_v1 import template_def
|
||||
|
||||
@ -32,3 +33,6 @@ class Driver(driver.HeatDriver):
|
||||
|
||||
def get_monitor(self, context, cluster):
|
||||
return k8s_monitor.K8sMonitor(context, cluster)
|
||||
|
||||
def get_scale_manager(self, context, osclient, cluster):
|
||||
return K8sScaleManager(context, osclient, cluster)
|
||||
|
@ -13,6 +13,7 @@
|
||||
# under the License.
|
||||
|
||||
from magnum.drivers.common import k8s_monitor
|
||||
from magnum.drivers.common.k8s_scale_manager import K8sScaleManager
|
||||
from magnum.drivers.heat import driver
|
||||
from magnum.drivers.k8s_fedora_atomic_v1 import template_def
|
||||
|
||||
@ -32,3 +33,6 @@ class Driver(driver.HeatDriver):
|
||||
|
||||
def get_monitor(self, context, cluster):
|
||||
return k8s_monitor.K8sMonitor(context, cluster)
|
||||
|
||||
def get_scale_manager(self, context, osclient, cluster):
|
||||
return K8sScaleManager(context, osclient, cluster)
|
||||
|
@ -13,6 +13,7 @@
|
||||
# under the License.
|
||||
|
||||
from magnum.drivers.common import k8s_monitor
|
||||
from magnum.drivers.common.k8s_scale_manager import K8sScaleManager
|
||||
from magnum.drivers.heat import driver
|
||||
from magnum.drivers.k8s_fedora_ironic_v1 import template_def
|
||||
|
||||
@ -32,3 +33,6 @@ class Driver(driver.HeatDriver):
|
||||
|
||||
def get_monitor(self, context, cluster):
|
||||
return k8s_monitor.K8sMonitor(context, cluster)
|
||||
|
||||
def get_scale_manager(self, context, osclient, cluster):
|
||||
return K8sScaleManager(context, osclient, cluster)
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
from magnum.drivers.heat import driver
|
||||
from magnum.drivers.mesos_ubuntu_v1 import monitor
|
||||
from magnum.drivers.mesos_ubuntu_v1.scale_manager import MesosScaleManager
|
||||
from magnum.drivers.mesos_ubuntu_v1 import template_def
|
||||
|
||||
|
||||
@ -32,3 +33,6 @@ class Driver(driver.HeatDriver):
|
||||
|
||||
def get_monitor(self, context, cluster):
|
||||
return monitor.MesosMonitor(context, cluster)
|
||||
|
||||
def get_scale_manager(self, context, osclient, cluster):
|
||||
return MesosScaleManager(context, osclient, cluster)
|
||||
|
43
magnum/drivers/mesos_ubuntu_v1/scale_manager.py
Normal file
43
magnum/drivers/mesos_ubuntu_v1/scale_manager.py
Normal file
@ -0,0 +1,43 @@
|
||||
# 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 marathon import MarathonClient
|
||||
from oslo_log import log as logging
|
||||
|
||||
from magnum.conductor.scale_manager import ScaleManager
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MesosScaleManager(ScaleManager):
|
||||
"""When scaling a mesos cluster, MesosScaleManager will inspect the
|
||||
|
||||
nodes and find out those with containers on them. Thus we can
|
||||
ask Heat to delete the nodes without containers. Note that this
|
||||
is a best effort basis -- Magnum doesn't have any synchronization
|
||||
with Marathon, so while Magnum is checking for the containers to
|
||||
choose nodes to remove, new containers can be deployed on the
|
||||
nodes to be removed.
|
||||
"""
|
||||
|
||||
def __init__(self, context, osclient, cluster):
|
||||
super(MesosScaleManager, self).__init__(context, osclient, cluster)
|
||||
|
||||
def _get_hosts_with_container(self, context, cluster):
|
||||
marathon_client = MarathonClient(
|
||||
'http://' + cluster.api_address + ':8080')
|
||||
hosts = set()
|
||||
for task in marathon_client.list_tasks():
|
||||
hosts.add(task.host)
|
||||
|
||||
return hosts
|
@ -16,34 +16,13 @@ import mock
|
||||
|
||||
from magnum.common import exception
|
||||
from magnum.conductor import scale_manager
|
||||
from magnum.drivers.common.k8s_scale_manager import K8sScaleManager
|
||||
from magnum.drivers.mesos_ubuntu_v1.scale_manager import MesosScaleManager
|
||||
from magnum.tests import base
|
||||
|
||||
|
||||
class TestScaleManager(base.TestCase):
|
||||
|
||||
@mock.patch('magnum.objects.Cluster.get_by_uuid')
|
||||
def test_get_scale_manager(self, mock_cluster_get):
|
||||
mock_context = mock.MagicMock()
|
||||
mock_osc = mock.MagicMock()
|
||||
k8s_cluster = mock.MagicMock()
|
||||
k8s_cluster.cluster_template.coe = 'kubernetes'
|
||||
mesos_cluster = mock.MagicMock()
|
||||
mesos_cluster.cluster_template.coe = 'mesos'
|
||||
invalid_cluster = mock.MagicMock()
|
||||
invalid_cluster.cluster_template.coe = 'fake'
|
||||
|
||||
mgr = scale_manager.get_scale_manager(
|
||||
mock_context, mock_osc, k8s_cluster)
|
||||
self.assertIsInstance(mgr, scale_manager.K8sScaleManager)
|
||||
|
||||
mgr = scale_manager.get_scale_manager(
|
||||
mock_context, mock_osc, mesos_cluster)
|
||||
self.assertIsInstance(mgr, scale_manager.MesosScaleManager)
|
||||
|
||||
mgr = scale_manager.get_scale_manager(
|
||||
mock_context, mock_osc, invalid_cluster)
|
||||
self.assertIsNone(mgr)
|
||||
|
||||
def _test_get_removal_nodes(
|
||||
self, mock_get_hosts, mock_get_num_of_removal,
|
||||
mock_is_scale_down, mock_get_by_uuid, is_scale_down,
|
||||
@ -215,7 +194,7 @@ class TestK8sScaleManager(base.TestCase):
|
||||
mock_api.list_namespaced_pod.return_value = pods
|
||||
mock_create_api.return_value = mock_api
|
||||
|
||||
mgr = scale_manager.K8sScaleManager(
|
||||
mgr = K8sScaleManager(
|
||||
mock.MagicMock(), mock.MagicMock(), mock.MagicMock())
|
||||
hosts = mgr._get_hosts_with_container(
|
||||
mock.MagicMock(), mock.MagicMock())
|
||||
@ -236,7 +215,7 @@ class TestMesosScaleManager(base.TestCase):
|
||||
tasks = [task_1, task_2]
|
||||
mock_list_tasks.return_value = tasks
|
||||
|
||||
mgr = scale_manager.MesosScaleManager(
|
||||
mgr = MesosScaleManager(
|
||||
mock.MagicMock(), mock.MagicMock(), mock.MagicMock())
|
||||
hosts = mgr._get_hosts_with_container(
|
||||
mock.MagicMock(), mock.MagicMock())
|
||||
|
Loading…
Reference in New Issue
Block a user