189 lines
6.1 KiB
Python
189 lines
6.1 KiB
Python
# Copyright 2014 NEC Corporation. All rights reserved.
|
|
#
|
|
# 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.
|
|
|
|
import abc
|
|
import six
|
|
|
|
from oslo_config import cfg
|
|
from pkg_resources import iter_entry_points
|
|
from stevedore import driver
|
|
|
|
from magnum.common import exception
|
|
from magnum.objects import cluster_template
|
|
|
|
|
|
CONF = cfg.CONF
|
|
|
|
|
|
@six.add_metaclass(abc.ABCMeta)
|
|
class Driver(object):
|
|
|
|
definitions = None
|
|
|
|
@classmethod
|
|
def load_entry_points(cls):
|
|
for entry_point in iter_entry_points('magnum.drivers'):
|
|
yield entry_point, entry_point.load(require=False)
|
|
|
|
@classmethod
|
|
def get_drivers(cls):
|
|
'''Retrieves cluster drivers from python entry_points.
|
|
|
|
Example:
|
|
|
|
With the following classes:
|
|
class Driver1(Driver):
|
|
provides = [
|
|
('server_type1', 'os1', 'coe1')
|
|
]
|
|
|
|
class Driver2(Driver):
|
|
provides = [
|
|
('server_type2', 'os2', 'coe2')
|
|
]
|
|
|
|
And the following entry_points:
|
|
|
|
magnum.drivers =
|
|
driver_name_1 = some.python.path:Driver1
|
|
driver_name_2 = some.python.path:Driver2
|
|
|
|
get_drivers will return:
|
|
{
|
|
(server_type1, os1, coe1):
|
|
{'driver_name_1': Driver1},
|
|
(server_type2, os2, coe2):
|
|
{'driver_name_2': Driver2}
|
|
}
|
|
|
|
:return: dict
|
|
'''
|
|
|
|
if not cls.definitions:
|
|
cls.definitions = dict()
|
|
for entry_point, def_class in cls.load_entry_points():
|
|
for cluster_type in def_class().provides:
|
|
cluster_type_tuple = (cluster_type['server_type'],
|
|
cluster_type['os'],
|
|
cluster_type['coe'])
|
|
providers = cls.definitions.setdefault(cluster_type_tuple,
|
|
dict())
|
|
providers['entry_point_name'] = entry_point.name
|
|
providers['class'] = def_class
|
|
|
|
return cls.definitions
|
|
|
|
@classmethod
|
|
def get_driver(cls, server_type, os, coe):
|
|
'''Get Driver.
|
|
|
|
Returns the Driver class for the provided cluster_type.
|
|
|
|
With the following classes:
|
|
class Driver1(Driver):
|
|
provides = [
|
|
('server_type1', 'os1', 'coe1')
|
|
]
|
|
|
|
class Driver2(Driver):
|
|
provides = [
|
|
('server_type2', 'os2', 'coe2')
|
|
]
|
|
|
|
And the following entry_points:
|
|
|
|
magnum.drivers =
|
|
driver_name_1 = some.python.path:Driver1
|
|
driver_name_2 = some.python.path:Driver2
|
|
|
|
get_driver('server_type2', 'os2', 'coe2')
|
|
will return: Driver2
|
|
|
|
:param server_type: The server_type the cluster definition will build
|
|
on
|
|
:param os: The operating system the cluster definition will build on
|
|
:param coe: The Container Orchestration Environment the cluster will
|
|
produce
|
|
|
|
:return: class
|
|
'''
|
|
|
|
definition_map = cls.get_drivers()
|
|
cluster_type = (server_type, os, coe)
|
|
|
|
if cluster_type not in definition_map:
|
|
raise exception.ClusterTypeNotSupported(
|
|
server_type=server_type,
|
|
os=os,
|
|
coe=coe)
|
|
driver_info = definition_map[cluster_type]
|
|
# TODO(muralia): once --drivername is supported as an input during
|
|
# cluster create, change the following line to use driver name for
|
|
# loading.
|
|
return driver.DriverManager("magnum.drivers",
|
|
driver_info['entry_point_name']).driver()
|
|
|
|
@classmethod
|
|
def get_driver_for_cluster(cls, context, cluster):
|
|
ct = cluster_template.ClusterTemplate.get_by_uuid(
|
|
context, cluster.cluster_template_id)
|
|
return cls.get_driver(ct.server_type, ct.cluster_distro, ct.coe)
|
|
|
|
def update_cluster_status(self, context, cluster):
|
|
'''Update the cluster status based on underlying orchestration
|
|
|
|
This is an optional method if your implementation does not need
|
|
to poll the orchestration for status updates (for example, your
|
|
driver uses some notification-based mechanism instead).
|
|
'''
|
|
return
|
|
|
|
@abc.abstractproperty
|
|
def provides(self):
|
|
'''return a list of (server_type, os, coe) tuples
|
|
|
|
Returns a list of cluster configurations supported by this driver
|
|
'''
|
|
raise NotImplementedError("Subclasses must implement 'provides'.")
|
|
|
|
@abc.abstractmethod
|
|
def create_cluster(self, context, cluster, cluster_create_timeout):
|
|
raise NotImplementedError("Subclasses must implement "
|
|
"'create_cluster'.")
|
|
|
|
@abc.abstractmethod
|
|
def update_cluster(self, context, cluster, scale_manager=None,
|
|
rollback=False):
|
|
raise NotImplementedError("Subclasses must implement "
|
|
"'update_cluster'.")
|
|
|
|
@abc.abstractmethod
|
|
def delete_cluster(self, context, cluster):
|
|
raise NotImplementedError("Subclasses must implement "
|
|
"'delete_cluster'.")
|
|
|
|
def get_monitor(self, context, cluster):
|
|
"""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
|
|
|
|
def rotate_ca_certificate(self, context, cluster):
|
|
raise exception.NotSupported(
|
|
"'rotate_ca_certificate' is not supported by this driver.")
|