Cluster Drivers

- Dynamically load drivers using stevedore
- Changed the entry points to reference drivers instead of
  template definitions
- Implement Create and update driver operations

Change-Id: I5c3259404c796e1935c872cf3109ffecae3cee02
Partially-Implements: blueprint bay-drivers
This commit is contained in:
murali allada 2016-08-25 10:14:21 -05:00
parent 45f071e36e
commit 104501cfe6
26 changed files with 648 additions and 435 deletions

View File

@ -12,9 +12,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import os
from heatclient.common import template_utils
from heatclient import exc
from oslo_log import log as logging
from oslo_service import loopingcall
@ -24,13 +21,12 @@ import six
from magnum.common import clients
from magnum.common import exception
from magnum.common import short_id
from magnum.conductor.handlers.common import cert_manager
from magnum.conductor.handlers.common import trust_manager
from magnum.conductor import scale_manager
from magnum.conductor import utils as conductor_utils
import magnum.conf
from magnum.drivers.common import template_def
from magnum.drivers.common import driver
from magnum.i18n import _
from magnum.i18n import _LE
from magnum.i18n import _LI
@ -42,79 +38,6 @@ CONF = magnum.conf.CONF
LOG = logging.getLogger(__name__)
def _extract_template_definition(context, cluster, scale_manager=None):
cluster_template = conductor_utils.retrieve_cluster_template(context,
cluster)
cluster_distro = cluster_template.cluster_distro
cluster_coe = cluster_template.coe
cluster_server_type = cluster_template.server_type
definition = template_def.TemplateDefinition.get_template_definition(
cluster_server_type,
cluster_distro,
cluster_coe)
return definition.extract_definition(context, cluster_template, cluster,
scale_manager=scale_manager)
def _get_env_files(template_path, env_rel_paths):
template_dir = os.path.dirname(template_path)
env_abs_paths = [os.path.join(template_dir, f) for f in env_rel_paths]
environment_files = []
env_map, merged_env = (
template_utils.process_multiple_environments_and_files(
env_paths=env_abs_paths, env_list_tracker=environment_files))
return environment_files, env_map
def _create_stack(context, osc, cluster, create_timeout):
template_path, heat_params, env_files = (
_extract_template_definition(context, cluster))
tpl_files, template = template_utils.get_template_contents(template_path)
environment_files, env_map = _get_env_files(template_path, env_files)
tpl_files.update(env_map)
# Make sure no duplicate stack name
stack_name = '%s-%s' % (cluster.name, short_id.generate_id())
if create_timeout:
heat_timeout = create_timeout
else:
# no create_timeout value was passed in to the request
# so falling back on configuration file value
heat_timeout = CONF.cluster_heat.create_timeout
fields = {
'stack_name': stack_name,
'parameters': heat_params,
'environment_files': environment_files,
'template': template,
'files': tpl_files,
'timeout_mins': heat_timeout
}
created_stack = osc.heat().stacks.create(**fields)
return created_stack
def _update_stack(context, osc, cluster, scale_manager=None, rollback=False):
template_path, heat_params, env_files = _extract_template_definition(
context, cluster, scale_manager=scale_manager)
tpl_files, template = template_utils.get_template_contents(template_path)
environment_files, env_map = _get_env_files(template_path, env_files)
tpl_files.update(env_map)
fields = {
'parameters': heat_params,
'environment_files': environment_files,
'template': template,
'files': tpl_files,
'disable_rollback': not rollback
}
return osc.heat().stacks.update(cluster.stack_id, **fields)
class Handler(object):
def __init__(self):
@ -135,8 +58,14 @@ class Handler(object):
context=context)
conductor_utils.notify_about_cluster_operation(
context, taxonomy.ACTION_CREATE, taxonomy.OUTCOME_PENDING)
created_stack = _create_stack(context, osc, cluster,
create_timeout)
# Get driver
ct = conductor_utils.retrieve_cluster_template(context, cluster)
cluster_driver = driver.Driver.get_driver(ct.server_type,
ct.cluster_distro,
ct.coe)
# Create cluster
created_stack = cluster_driver.create_stack(context, osc, cluster,
create_timeout)
except Exception as e:
cluster.status = fields.ClusterStatus.CREATE_FAILED
cluster.status_reason = six.text_type(e)
@ -154,7 +83,7 @@ class Handler(object):
cluster.status = fields.ClusterStatus.CREATE_IN_PROGRESS
cluster.create()
self._poll_and_check(osc, cluster)
self._poll_and_check(osc, cluster, cluster_driver)
return cluster
@ -189,8 +118,14 @@ class Handler(object):
conductor_utils.notify_about_cluster_operation(
context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_PENDING)
_update_stack(context, osc, cluster, manager, rollback)
self._poll_and_check(osc, cluster)
# Get driver
ct = conductor_utils.retrieve_cluster_template(context, cluster)
cluster_driver = driver.Driver.get_driver(ct.server_type,
ct.cluster_distro,
ct.coe)
# Create cluster
cluster_driver.update_stack(context, osc, cluster, manager, rollback)
self._poll_and_check(osc, cluster, cluster_driver)
return cluster
@ -241,26 +176,23 @@ class Handler(object):
return None
def _poll_and_check(self, osc, cluster):
poller = HeatPoller(osc, cluster)
def _poll_and_check(self, osc, cluster, cluster_driver=None):
poller = HeatPoller(osc, cluster, cluster_driver)
lc = loopingcall.FixedIntervalLoopingCall(f=poller.poll_and_check)
lc.start(CONF.cluster_heat.wait_interval, True)
class HeatPoller(object):
def __init__(self, openstack_client, cluster):
def __init__(self, openstack_client, cluster, cluster_driver=None):
self.openstack_client = openstack_client
self.context = self.openstack_client.context
self.cluster = cluster
self.attempts = 0
self.cluster_template = conductor_utils.retrieve_cluster_template(
self.context, cluster)
self.template_def = \
template_def.TemplateDefinition.get_template_definition(
self.cluster_template.server_type,
self.cluster_template.cluster_distro,
self.cluster_template.coe)
if cluster_driver:
self.template_def = cluster_driver.get_template_definition()
def poll_and_check(self):
# TODO(yuanying): temporary implementation to update api_address,
@ -356,11 +288,7 @@ class HeatPoller(object):
if stack_param:
self.cluster.coe_version = stack.parameters[stack_param]
tdef = template_def.TemplateDefinition.get_template_definition(
self.cluster_template.server_type,
self.cluster_template.cluster_distro, self.cluster_template.coe)
version_module_path = tdef.driver_module_path+'.version'
version_module_path = self.template_def.driver_module_path+'.version'
try:
ver = importutils.import_module(version_module_path)
container_version = ver.container_version

View File

@ -23,6 +23,10 @@ cluster_def_opts = [
help=_('Url for etcd public discovery endpoint.'),
deprecated_group='bay'),
cfg.ListOpt('enabled_definitions',
deprecated_for_removal=True,
deprecated_reason=_('This configuration option is no longer '
'used. Installing a new driver enables '
'it for use automatically.'),
default=['magnum_vm_atomic_k8s', 'magnum_bm_fedora_k8s',
'magnum_vm_coreos_k8s', 'magnum_vm_atomic_swarm',
'magnum_vm_ubuntu_mesos'],

View File

@ -0,0 +1,208 @@
# 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 os
from heatclient.common import template_utils
from oslo_config import cfg
from oslo_log import log as logging
from pkg_resources import iter_entry_points
from stevedore import driver
from magnum.common import exception
from magnum.common import short_id
from magnum.conductor import utils as conductor_utils
CONF = cfg.CONF
LOG = logging.getLogger(__name__)
def _extract_template_definition(context, cluster, scale_manager=None):
cluster_template = conductor_utils.retrieve_cluster_template(context,
cluster)
cluster_driver = Driver().get_driver(cluster_template.server_type,
cluster_template.cluster_distro,
cluster_template.coe)
definition = cluster_driver.get_template_definition()
return definition.extract_definition(context, cluster_template, cluster,
scale_manager=scale_manager)
def _get_env_files(template_path, env_rel_paths):
template_dir = os.path.dirname(template_path)
env_abs_paths = [os.path.join(template_dir, f) for f in env_rel_paths]
environment_files = []
env_map, merged_env = (
template_utils.process_multiple_environments_and_files(
env_paths=env_abs_paths, env_list_tracker=environment_files))
return environment_files, env_map
class Driver(object):
definitions = None
provides = list()
@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()
def create_stack(self, context, osc, cluster, cluster_create_timeout):
template_path, heat_params, env_files = (
_extract_template_definition(context, cluster))
tpl_files, template = template_utils.get_template_contents(
template_path)
environment_files, env_map = _get_env_files(template_path, env_files)
tpl_files.update(env_map)
# Make sure no duplicate stack name
stack_name = '%s-%s' % (cluster.name, short_id.generate_id())
if cluster_create_timeout:
heat_timeout = cluster_create_timeout
else:
# no cluster_create_timeout value was passed in to the request
# so falling back on configuration file value
heat_timeout = cfg.CONF.cluster_heat.create_timeout
fields = {
'stack_name': stack_name,
'parameters': heat_params,
'environment_files': environment_files,
'template': template,
'files': tpl_files,
'timeout_mins': heat_timeout
}
created_stack = osc.heat().stacks.create(**fields)
return created_stack
def update_stack(self, context, osc, cluster, scale_manager=None,
rollback=False):
template_path, heat_params, env_files = _extract_template_definition(
context, cluster, scale_manager=scale_manager)
tpl_files, template = template_utils.get_template_contents(
template_path)
environment_files, env_map = _get_env_files(template_path, env_files)
tpl_files.update(env_map)
fields = {
'parameters': heat_params,
'environment_files': environment_files,
'template': template,
'files': tpl_files,
'disable_rollback': not rollback
}
return osc.heat().stacks.update(cluster.stack_id, **fields)

View File

@ -16,7 +16,6 @@ import ast
from oslo_config import cfg
from oslo_log import log as logging
from pkg_resources import iter_entry_points
import requests
import six
@ -126,118 +125,11 @@ class TemplateDefinition(object):
and Heat templates. Each TemplateDefinition has a mapping of Heat
parameters.
'''
definitions = None
provides = list()
def __init__(self):
self.param_mappings = list()
self.output_mappings = list()
@staticmethod
def load_entry_points():
for entry_point in iter_entry_points('magnum.template_definitions'):
yield entry_point, entry_point.load(require=False)
@classmethod
def get_template_definitions(cls):
'''Retrieves cluster definitions from python entry_points.
Example:
With the following classes:
class TemplateDefinition1(TemplateDefinition):
provides = [
('server_type1', 'os1', 'coe1')
]
class TemplateDefinition2(TemplateDefinition):
provides = [
('server_type2', 'os2', 'coe2')
]
And the following entry_points:
magnum.template_definitions =
template_name_1 = some.python.path:TemplateDefinition1
template_name_2 = some.python.path:TemplateDefinition2
get_template_definitions will return:
{
(server_type1, os1, coe1):
{'template_name_1': TemplateDefinition1},
(server_type2, os2, coe2):
{'template_name_2': TemplateDefinition2}
}
: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] = def_class
return cls.definitions
@classmethod
def get_template_definition(cls, server_type, os, coe):
'''Get enabled TemplateDefinitions.
Returns the enabled TemplateDefinition class for the provided
cluster_type.
With the following classes:
class TemplateDefinition1(TemplateDefinition):
provides = [
('server_type1', 'os1', 'coe1')
]
class TemplateDefinition2(TemplateDefinition):
provides = [
('server_type2', 'os2', 'coe2')
]
And the following entry_points:
magnum.template_definitions =
template_name_1 = some.python.path:TemplateDefinition1
template_name_2 = some.python.path:TemplateDefinition2
get_template_name_1_definition('server_type2', 'os2', 'coe2')
will return: TemplateDefinition2
: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_template_definitions()
cluster_type = (server_type, os, coe)
if cluster_type not in definition_map:
raise exception.ClusterTypeNotSupported(
server_type=server_type,
os=os,
coe=coe)
type_definitions = definition_map[cluster_type]
for name in CONF.cluster.enabled_definitions:
if name in type_definitions:
return type_definitions[name]()
raise exception.ClusterTypeNotEnabled(
server_type=server_type, os=os, coe=coe)
def add_parameter(self, *args, **kwargs):
param = ParameterMapping(*args, **kwargs)
self.param_mappings.append(param)

View File

@ -0,0 +1,27 @@
# Copyright 2016 Rackspace Inc. 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.
from magnum.drivers.common import driver
from magnum.drivers.k8s_coreos_v1 import template_def
class Driver(driver.Driver):
provides = [
{'server_type': 'vm',
'os': 'coreos',
'coe': 'kubernetes'},
]
def get_template_definition(self):
return template_def.CoreOSK8sTemplateDefinition()

View File

@ -23,12 +23,6 @@ CONF = cfg.CONF
class CoreOSK8sTemplateDefinition(k8s_template_def.K8sTemplateDefinition):
"""Kubernetes template for CoreOS VM."""
provides = [
{'server_type': 'vm',
'os': 'coreos',
'coe': 'kubernetes'},
]
def __init__(self):
super(CoreOSK8sTemplateDefinition, self).__init__()
self.add_output('kube_minions',

View File

@ -13,5 +13,5 @@
# limitations under the License.
version = '1.0.0'
driver = 'k8s_coreos'
driver = 'k8s_coreos_v1'
container_version = '1.11.2'

View File

@ -0,0 +1,27 @@
# Copyright 2016 Rackspace Inc. 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.
from magnum.drivers.common import driver
from magnum.drivers.k8s_fedora_atomic_v1 import template_def
class Driver(driver.Driver):
provides = [
{'server_type': 'vm',
'os': 'fedora-atomic',
'coe': 'kubernetes'},
]
def get_template_definition(self):
return template_def.AtomicK8sTemplateDefinition()

View File

@ -23,12 +23,6 @@ CONF = cfg.CONF
class AtomicK8sTemplateDefinition(kftd.K8sFedoraTemplateDefinition):
"""Kubernetes template for a Fedora Atomic VM."""
provides = [
{'server_type': 'vm',
'os': 'fedora-atomic',
'coe': 'kubernetes'},
]
@property
def driver_module_path(self):
return __name__[:__name__.rindex('.')]

View File

@ -13,5 +13,5 @@
# limitations under the License.
version = '1.0.0'
driver = 'k8s_fedora_atomic'
driver = 'k8s_fedora_atomic_v1'
container_version = '1.9.1'

View File

@ -0,0 +1,27 @@
# Copyright 2016 Rackspace Inc. 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.
from magnum.drivers.common import driver
from magnum.drivers.k8s_fedora_ironic_v1 import template_def
class Driver(driver.Driver):
provides = [
{'server_type': 'bm',
'os': 'fedora',
'coe': 'kubernetes'},
]
def get_template_definition(self):
return template_def.FedoraK8sIronicTemplateDefinition()

View File

@ -27,12 +27,6 @@ LOG = logging.getLogger(__name__)
class FedoraK8sIronicTemplateDefinition(kftd.K8sFedoraTemplateDefinition):
"""Kubernetes template for a Fedora Baremetal."""
provides = [
{'server_type': 'bm',
'os': 'fedora',
'coe': 'kubernetes'},
]
def __init__(self):
super(FedoraK8sIronicTemplateDefinition, self).__init__()
self.add_parameter('fixed_subnet',

View File

@ -0,0 +1,17 @@
# Copyright 2016 - Rackspace Hosting
#
# 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.
version = '1.0.0'
driver = 'k8s_fedora_ironic_v1'
container_version = '1.9.1'

View File

@ -0,0 +1,27 @@
# Copyright 2016 Rackspace Inc. 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.
from magnum.drivers.common import driver
from magnum.drivers.mesos_ubuntu_v1 import template_def
class Driver(driver.Driver):
provides = [
{'server_type': 'vm',
'os': 'ubuntu',
'coe': 'mesos'},
]
def get_template_definition(self):
return template_def.UbuntuMesosTemplateDefinition()

View File

@ -19,10 +19,6 @@ from magnum.drivers.common import template_def
class UbuntuMesosTemplateDefinition(template_def.BaseTemplateDefinition):
"""Mesos template for Ubuntu VM."""
provides = [
{'server_type': 'vm', 'os': 'ubuntu', 'coe': 'mesos'},
]
def __init__(self):
super(UbuntuMesosTemplateDefinition, self).__init__()
self.add_parameter('external_network',

View File

@ -13,5 +13,5 @@
# limitations under the License.
version = '1.0.0'
driver = 'mesos_ubuntu'
driver = 'mesos_ubuntu_v1'
container_version = '1.9.1'

View File

@ -0,0 +1,27 @@
# Copyright 2016 Rackspace Inc. 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.
from magnum.drivers.common import driver
from magnum.drivers.swarm_fedora_atomic_v1 import template_def
class Driver(driver.Driver):
provides = [
{'server_type': 'vm',
'os': 'fedora-atomic',
'coe': 'swarm'},
]
def get_template_definition(self):
return template_def.AtomicSwarmTemplateDefinition()

View File

@ -22,10 +22,6 @@ CONF = cfg.CONF
class AtomicSwarmTemplateDefinition(sftd.SwarmFedoraTemplateDefinition):
"""Docker swarm template for a Fedora Atomic VM."""
provides = [
{'server_type': 'vm', 'os': 'fedora-atomic', 'coe': 'swarm'},
]
@property
def driver_module_path(self):
return __name__[:__name__.rindex('.')]

View File

@ -13,5 +13,5 @@
# limitations under the License.
version = '1.0.0'
driver = 'swarm_atomic'
driver = 'swarm_fedora_atomic_v1'
container_version = '1.9.1'

View File

@ -1,32 +0,0 @@
# 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 magnum.drivers.common import template_def as tdef
from magnum.tests import base
class TestTemplates(base.TestCase):
def test_templates_list(self):
entry_points = list(tdef.TemplateDefinition.load_entry_points())
self.assertEqual(5, len(entry_points))
templates = []
for entry_point, def_class in entry_points:
templates.append(def_class.__name__)
self.assertEqual(['AtomicK8sTemplateDefinition',
'AtomicSwarmTemplateDefinition',
'CoreOSK8sTemplateDefinition',
'FedoraK8sIronicTemplateDefinition',
'UbuntuMesosTemplateDefinition'],
sorted(templates))

View File

@ -25,6 +25,7 @@ from pycadf import cadftaxonomy as taxonomy
from magnum.common import exception
from magnum.conductor.handlers import cluster_conductor
import magnum.conf
from magnum.drivers.k8s_fedora_atomic_v1 import driver as k8s_atomic_dr
from magnum import objects
from magnum.objects.fields import ClusterStatus as cluster_status
from magnum.tests import base
@ -51,11 +52,11 @@ class TestHandler(db_base.DbTestCase):
@patch('magnum.conductor.scale_manager.ScaleManager')
@patch(
'magnum.conductor.handlers.cluster_conductor.Handler._poll_and_check')
@patch('magnum.conductor.handlers.cluster_conductor._update_stack')
@patch('magnum.drivers.common.driver.Driver.get_driver')
@patch('magnum.common.clients.OpenStackClients')
def test_update_node_count_success(
self, mock_openstack_client_class,
mock_update_stack, mock_poll_and_check,
mock_driver, mock_poll_and_check,
mock_scale_manager):
def side_effect(*args, **kwargs):
self.cluster.node_count = 2
@ -67,6 +68,8 @@ class TestHandler(db_base.DbTestCase):
mock_heat_client.stacks.get.return_value = mock_heat_stack
mock_openstack_client = mock_openstack_client_class.return_value
mock_openstack_client.heat.return_value = mock_heat_client
mock_dr = mock.MagicMock()
mock_driver.return_value = mock_dr
self.cluster.node_count = 2
self.handler.cluster_update(self.context, self.cluster)
@ -78,7 +81,7 @@ class TestHandler(db_base.DbTestCase):
self.assertEqual(
taxonomy.OUTCOME_PENDING, notifications[0].payload['outcome'])
mock_update_stack.assert_called_once_with(
mock_dr.update_stack.assert_called_once_with(
self.context, mock_openstack_client, self.cluster,
mock_scale_manager.return_value, False)
cluster = objects.Cluster.get(self.context, self.cluster.uuid)
@ -86,11 +89,10 @@ class TestHandler(db_base.DbTestCase):
@patch(
'magnum.conductor.handlers.cluster_conductor.Handler._poll_and_check')
@patch('magnum.conductor.handlers.cluster_conductor._update_stack')
@patch('magnum.common.clients.OpenStackClients')
def test_update_node_count_failure(
self, mock_openstack_client_class,
mock_update_stack, mock_poll_and_check):
mock_poll_and_check):
def side_effect(*args, **kwargs):
self.cluster.node_count = 2
self.cluster.save()
@ -119,11 +121,11 @@ class TestHandler(db_base.DbTestCase):
@patch('magnum.conductor.scale_manager.ScaleManager')
@patch(
'magnum.conductor.handlers.cluster_conductor.Handler._poll_and_check')
@patch('magnum.conductor.handlers.cluster_conductor._update_stack')
@patch('magnum.drivers.common.driver.Driver.get_driver')
@patch('magnum.common.clients.OpenStackClients')
def _test_update_cluster_status_complete(
self, expect_status, mock_openstack_client_class,
mock_update_stack, mock_poll_and_check,
mock_driver, mock_poll_and_check,
mock_scale_manager):
def side_effect(*args, **kwargs):
self.cluster.node_count = 2
@ -135,6 +137,8 @@ class TestHandler(db_base.DbTestCase):
mock_heat_client.stacks.get.return_value = mock_heat_stack
mock_openstack_client = mock_openstack_client_class.return_value
mock_openstack_client.heat.return_value = mock_heat_client
mock_dr = mock.MagicMock()
mock_driver.return_value = mock_dr
self.cluster.node_count = 2
self.handler.cluster_update(self.context, self.cluster)
@ -146,7 +150,7 @@ class TestHandler(db_base.DbTestCase):
self.assertEqual(
taxonomy.OUTCOME_PENDING, notifications[0].payload['outcome'])
mock_update_stack.assert_called_once_with(
mock_dr.update_stack.assert_called_once_with(
self.context, mock_openstack_client, self.cluster,
mock_scale_manager.return_value, False)
cluster = objects.Cluster.get(self.context, self.cluster.uuid)
@ -183,10 +187,10 @@ class TestHandler(db_base.DbTestCase):
@patch('magnum.conductor.handlers.cluster_conductor.HeatPoller')
@patch('magnum.conductor.handlers.cluster_conductor.trust_manager')
@patch('magnum.conductor.handlers.cluster_conductor.cert_manager')
@patch('magnum.conductor.handlers.cluster_conductor._create_stack')
@patch('magnum.drivers.common.driver.Driver.get_driver')
@patch('magnum.common.clients.OpenStackClients')
def test_create(self, mock_openstack_client_class,
mock_create_stack, mock_cm, mock_trust_manager,
mock_driver, mock_cm, mock_trust_manager,
mock_heat_poller_class):
timeout = 15
mock_poller = mock.MagicMock()
@ -194,11 +198,13 @@ class TestHandler(db_base.DbTestCase):
mock_heat_poller_class.return_value = mock_poller
osc = mock.sentinel.osc
mock_openstack_client_class.return_value = osc
mock_dr = mock.MagicMock()
mock_driver.return_value = mock_dr
def create_stack_side_effect(context, osc, cluster, timeout):
return {'stack': {'id': 'stack-id'}}
mock_create_stack.side_effect = create_stack_side_effect
mock_dr.create_stack.side_effect = create_stack_side_effect
# FixMe(eliqiao): cluster_create will call cluster.create()
# again, this so bad because we have already called it in setUp
@ -221,9 +227,9 @@ class TestHandler(db_base.DbTestCase):
self.assertEqual(
taxonomy.OUTCOME_PENDING, notifications[0].payload['outcome'])
mock_create_stack.assert_called_once_with(self.context,
mock.sentinel.osc,
self.cluster, timeout)
mock_dr.create_stack.assert_called_once_with(self.context,
mock.sentinel.osc,
self.cluster, timeout)
mock_cm.generate_certificates_to_cluster.assert_called_once_with(
self.cluster, context=self.context)
self.assertEqual(cluster_status.CREATE_IN_PROGRESS, cluster.status)
@ -264,14 +270,16 @@ class TestHandler(db_base.DbTestCase):
@patch('magnum.objects.Cluster.create')
@patch('magnum.conductor.handlers.cluster_conductor.trust_manager')
@patch('magnum.conductor.handlers.cluster_conductor.cert_manager')
@patch('magnum.conductor.handlers.cluster_conductor._create_stack')
@patch('magnum.drivers.common.driver.Driver.get_driver')
@patch('magnum.common.clients.OpenStackClients')
def test_create_handles_bad_request(self, mock_openstack_client_class,
mock_create_stack,
mock_driver,
mock_cert_manager,
mock_trust_manager,
mock_cluster_create):
mock_create_stack.side_effect = exc.HTTPBadRequest
mock_dr = mock.MagicMock()
mock_driver.return_value = mock_dr
mock_dr.create_stack.side_effect = exc.HTTPBadRequest
self._test_create_failed(
mock_openstack_client_class,
@ -321,10 +329,8 @@ class TestHandler(db_base.DbTestCase):
@patch('magnum.objects.Cluster.create')
@patch('magnum.conductor.handlers.cluster_conductor.trust_manager')
@patch('magnum.conductor.handlers.cluster_conductor.cert_manager')
@patch('magnum.conductor.handlers.cluster_conductor._create_stack')
@patch('magnum.common.clients.OpenStackClients')
def test_create_with_trust_failed(self, mock_openstack_client_class,
mock_create_stack,
mock_cert_manager,
mock_trust_manager,
mock_cluster_create):
@ -350,18 +356,20 @@ class TestHandler(db_base.DbTestCase):
@patch('magnum.objects.Cluster.create')
@patch('magnum.conductor.handlers.cluster_conductor.trust_manager')
@patch('magnum.conductor.handlers.cluster_conductor.cert_manager')
@patch('magnum.conductor.handlers.cluster_conductor._create_stack')
@patch('magnum.drivers.common.driver.Driver.get_driver')
@patch('magnum.common.clients.OpenStackClients')
def test_create_with_invalid_unicode_name(self,
mock_openstack_client_class,
mock_create_stack,
mock_driver,
mock_cert_manager,
mock_trust_manager,
mock_cluster_create):
error_message = six.u("""Invalid stack name 测试集群-zoyh253geukk
must contain only alphanumeric or "_-."
characters, must start with alpha""")
mock_create_stack.side_effect = exc.HTTPBadRequest(error_message)
mock_dr = mock.MagicMock()
mock_driver.return_value = mock_dr
mock_dr.create_stack.side_effect = exc.HTTPBadRequest(error_message)
self._test_create_failed(
mock_openstack_client_class,
@ -386,28 +394,30 @@ class TestHandler(db_base.DbTestCase):
@patch('heatclient.common.template_utils'
'.process_multiple_environments_and_files')
@patch('heatclient.common.template_utils.get_template_contents')
@patch('magnum.conductor.handlers.cluster_conductor'
'._extract_template_definition')
@patch('magnum.conductor.handlers.cluster_conductor.trust_manager')
@patch('magnum.conductor.handlers.cluster_conductor.cert_manager')
@patch('magnum.conductor.handlers.cluster_conductor.short_id')
@patch('magnum.drivers.common.driver._extract_template_definition')
@patch('magnum.drivers.common.driver.Driver.get_driver')
@patch('magnum.common.clients.OpenStackClients')
@patch('magnum.common.short_id.generate_id')
def test_create_with_environment(self,
mock_openstack_client_class,
mock_short_id,
mock_openstack_client_class,
mock_driver,
mock_extract_tmpl_def,
mock_cert_manager,
mock_trust_manager,
mock_extract_tmpl_def,
mock_get_template_contents,
mock_process_mult,
mock_heat_poller_class):
timeout = 15
self.cluster.cluster_template_id = self.cluster_template.uuid
cluster_name = self.cluster.name
mock_short_id.generate_id.return_value = 'short_id'
mock_poller = mock.MagicMock()
mock_poller.poll_and_check.return_value = loopingcall.LoopingCallDone()
mock_heat_poller_class.return_value = mock_poller
mock_driver.return_value = k8s_atomic_dr.Driver()
mock_short_id.return_value = 'short_id'
mock_extract_tmpl_def.return_value = (
'the/template/path.yaml',
@ -515,7 +525,8 @@ class TestHeatPoller(base.TestCase):
@patch('magnum.conductor.utils.retrieve_cluster_template')
@patch('oslo_config.cfg')
@patch('magnum.common.clients.OpenStackClients')
def setup_poll_test(self, mock_openstack_client, cfg,
@patch('magnum.drivers.common.driver.Driver.get_driver')
def setup_poll_test(self, mock_driver, mock_openstack_client, cfg,
mock_retrieve_cluster_template):
cfg.CONF.cluster_heat.max_attempts = 10
@ -529,7 +540,9 @@ class TestHeatPoller(base.TestCase):
cluster_template = objects.ClusterTemplate(self.context,
**cluster_template_dict)
mock_retrieve_cluster_template.return_value = cluster_template
poller = cluster_conductor.HeatPoller(mock_openstack_client, cluster)
mock_driver.return_value = k8s_atomic_dr.Driver()
poller = cluster_conductor.HeatPoller(mock_openstack_client, cluster,
k8s_atomic_dr.Driver())
poller.get_version_info = mock.MagicMock()
return (mock_heat_stack, cluster, poller)

View File

@ -15,8 +15,10 @@
import mock
from mock import patch
from magnum.conductor.handlers import cluster_conductor
import magnum.conf
from magnum.drivers.common import driver
from magnum.drivers.k8s_coreos_v1 import driver as k8s_coreos_dr
from magnum.drivers.k8s_fedora_atomic_v1 import driver as k8s_dr
from magnum import objects
from magnum.tests import base
@ -88,15 +90,18 @@ class TestClusterConductorWithK8s(base.TestCase):
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get):
self._test_extract_template_definition(
mock_objects_cluster_template_get_by_uuid, mock_get)
mock_driver, mock_objects_cluster_template_get_by_uuid, mock_get)
def _test_extract_template_definition(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get,
missing_attr=None):
@ -114,11 +119,12 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_resp.text = expected_result
mock_get.return_value = mock_resp
cluster = objects.Cluster(self.context, **self.cluster_dict)
mock_driver.return_value = k8s_dr.Driver()
(template_path,
definition,
env_files) = cluster_conductor._extract_template_definition(
self.context, cluster)
env_files) = driver._extract_template_definition(self.context,
cluster)
mapping = {
'dns_nameserver': 'dns_nameserver',
@ -191,8 +197,10 @@ class TestClusterConductorWithK8s(base.TestCase):
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_with_registry(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get):
self.cluster_template_dict['registry_enabled'] = True
@ -206,6 +214,7 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_resp.text = expected_result
mock_get.return_value = mock_resp
cluster = objects.Cluster(self.context, **self.cluster_dict)
mock_driver.return_value = k8s_dr.Driver()
CONF.set_override('swift_region',
'RegionOne',
@ -213,8 +222,8 @@ class TestClusterConductorWithK8s(base.TestCase):
(template_path,
definition,
env_files) = cluster_conductor._extract_template_definition(
self.context, cluster)
env_files) = driver._extract_template_definition(self.context,
cluster)
expected = {
'auth_url': 'http://192.168.10.10:5000/v3',
@ -263,8 +272,10 @@ class TestClusterConductorWithK8s(base.TestCase):
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_coreos_with_disovery(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get):
self.cluster_template_dict['cluster_distro'] = 'coreos'
@ -278,11 +289,12 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_resp.text = expected_result
mock_get.return_value = mock_resp
cluster = objects.Cluster(self.context, **self.cluster_dict)
mock_driver.return_value = k8s_coreos_dr.Driver()
(template_path,
definition,
env_files) = cluster_conductor._extract_template_definition(
self.context, cluster)
env_files) = driver._extract_template_definition(self.context,
cluster)
expected = {
'ssh_key_name': 'keypair_id',
@ -322,8 +334,10 @@ class TestClusterConductorWithK8s(base.TestCase):
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_coreos_no_discoveryurl(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
reqget):
self.cluster_template_dict['cluster_distro'] = 'coreos'
@ -335,11 +349,12 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_objects_cluster_template_get_by_uuid.return_value = \
cluster_template
cluster = objects.Cluster(self.context, **self.cluster_dict)
mock_driver.return_value = k8s_coreos_dr.Driver()
(template_path,
definition,
env_files) = cluster_conductor._extract_template_definition(
self.context, cluster)
env_files) = driver._extract_template_definition(self.context,
cluster)
expected = {
'ssh_key_name': 'keypair_id',
@ -379,107 +394,145 @@ class TestClusterConductorWithK8s(base.TestCase):
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_without_dns(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get):
mock_driver.return_value = k8s_dr.Driver()
self._test_extract_template_definition(
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get,
missing_attr='dns_nameserver')
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_without_server_image(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get):
mock_driver.return_value = k8s_dr.Driver()
self._test_extract_template_definition(
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get,
missing_attr='image_id')
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_without_minion_flavor(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get):
mock_driver.return_value = k8s_dr.Driver()
self._test_extract_template_definition(
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get,
missing_attr='flavor_id')
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_without_docker_volume_size(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get):
mock_driver.return_value = k8s_dr.Driver()
self._test_extract_template_definition(
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get,
missing_attr='docker_volume_size')
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_without_docker_storage_driver(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get):
mock_driver.return_value = k8s_dr.Driver()
self._test_extract_template_definition(
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get,
missing_attr='docker_storage_driver')
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_without_master_flavor(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get):
mock_driver.return_value = k8s_dr.Driver()
self._test_extract_template_definition(
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get,
missing_attr='master_flavor_id')
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_without_apiserver_port(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get):
mock_driver.return_value = k8s_dr.Driver()
self._test_extract_template_definition(
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get,
missing_attr='apiserver_port')
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_without_node_count(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get):
mock_driver.return_value = k8s_dr.Driver()
self._test_extract_template_definition(
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get,
missing_attr='node_count')
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_without_master_count(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get):
mock_driver.return_value = k8s_dr.Driver()
self._test_extract_template_definition(
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get,
missing_attr='master_count')
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_without_discovery_url(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
reqget):
cluster_template = objects.ClusterTemplate(
@ -489,6 +542,7 @@ class TestClusterConductorWithK8s(base.TestCase):
cluster_dict = self.cluster_dict
cluster_dict['discovery_url'] = None
cluster = objects.Cluster(self.context, **cluster_dict)
mock_driver.return_value = k8s_dr.Driver()
CONF.set_override('etcd_discovery_service_endpoint_format',
'http://etcd/test?size=%(size)d',
@ -498,8 +552,8 @@ class TestClusterConductorWithK8s(base.TestCase):
(template_path,
definition,
env_files) = cluster_conductor._extract_template_definition(
self.context, cluster)
env_files) = driver._extract_template_definition(self.context,
cluster)
expected = {
'ssh_key_name': 'keypair_id',
@ -546,8 +600,7 @@ class TestClusterConductorWithK8s(base.TestCase):
@patch('magnum.common.short_id.generate_id')
@patch('heatclient.common.template_utils.get_template_contents')
@patch('magnum.conductor.handlers.cluster_conductor'
'._extract_template_definition')
@patch('magnum.drivers.common.driver._extract_template_definition')
def test_create_stack(self,
mock_extract_template_definition,
mock_get_template_contents,
@ -570,8 +623,8 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_cluster = mock.MagicMock()
mock_cluster.name = dummy_cluster_name
cluster_conductor._create_stack(self.context, mock_osc,
mock_cluster, expected_timeout)
k8s_dr.Driver().create_stack(self.context, mock_osc,
mock_cluster, expected_timeout)
expected_args = {
'stack_name': expected_stack_name,
@ -585,8 +638,7 @@ class TestClusterConductorWithK8s(base.TestCase):
@patch('magnum.common.short_id.generate_id')
@patch('heatclient.common.template_utils.get_template_contents')
@patch('magnum.conductor.handlers.cluster_conductor'
'._extract_template_definition')
@patch('magnum.drivers.common.driver._extract_template_definition')
def test_create_stack_no_timeout_specified(
self,
mock_extract_template_definition,
@ -610,8 +662,8 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_cluster = mock.MagicMock()
mock_cluster.name = dummy_cluster_name
cluster_conductor._create_stack(self.context, mock_osc,
mock_cluster, None)
k8s_dr.Driver().create_stack(self.context, mock_osc,
mock_cluster, None)
expected_args = {
'stack_name': expected_stack_name,
@ -625,8 +677,7 @@ class TestClusterConductorWithK8s(base.TestCase):
@patch('magnum.common.short_id.generate_id')
@patch('heatclient.common.template_utils.get_template_contents')
@patch('magnum.conductor.handlers.cluster_conductor'
'._extract_template_definition')
@patch('magnum.drivers.common.driver._extract_template_definition')
def test_create_stack_timeout_is_zero(
self,
mock_extract_template_definition,
@ -651,8 +702,8 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_cluster = mock.MagicMock()
mock_cluster.name = dummy_cluster_name
cluster_conductor._create_stack(self.context, mock_osc,
mock_cluster, cluster_timeout)
k8s_dr.Driver().create_stack(self.context, mock_osc,
mock_cluster, cluster_timeout)
expected_args = {
'stack_name': expected_stack_name,
@ -665,8 +716,7 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_heat_client.stacks.create.assert_called_once_with(**expected_args)
@patch('heatclient.common.template_utils.get_template_contents')
@patch('magnum.conductor.handlers.cluster_conductor'
'._extract_template_definition')
@patch('magnum.drivers.common.driver._extract_template_definition')
def test_update_stack(self,
mock_extract_template_definition,
mock_get_template_contents):
@ -685,7 +735,7 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_cluster = mock.MagicMock()
mock_cluster.stack_id = mock_stack_id
cluster_conductor._update_stack({}, mock_osc, mock_cluster)
k8s_dr.Driver().update_stack({}, mock_osc, mock_cluster)
expected_args = {
'parameters': {},

View File

@ -17,6 +17,8 @@ from mock import patch
from oslo_service import loopingcall
from magnum.conductor.handlers import cluster_conductor
from magnum.drivers.common import driver
from magnum.drivers.mesos_ubuntu_v1 import driver as mesos_dr
from magnum import objects
from magnum.objects.fields import ClusterStatus as cluster_status
from magnum.tests import base
@ -78,19 +80,22 @@ class TestClusterConductorWithMesos(base.TestCase):
self.mock_osc_class.return_value = self.mock_osc
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_all_values(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid):
cluster_template = objects.ClusterTemplate(
self.context, **self.cluster_template_dict)
mock_objects_cluster_template_get_by_uuid.return_value = \
cluster_template
cluster = objects.Cluster(self.context, **self.cluster_dict)
mock_driver.return_value = mesos_dr.Driver()
(template_path,
definition,
env_files) = cluster_conductor._extract_template_definition(
self.context, cluster)
env_files) = driver._extract_template_definition(self.context,
cluster)
expected = {
'ssh_key_name': 'keypair_id',
@ -128,8 +133,10 @@ class TestClusterConductorWithMesos(base.TestCase):
env_files)
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_only_required(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid):
not_required = ['image_id', 'master_flavor_id', 'flavor_id',
'dns_nameserver', 'fixed_network', 'http_proxy',
@ -142,11 +149,12 @@ class TestClusterConductorWithMesos(base.TestCase):
mock_objects_cluster_template_get_by_uuid.return_value = \
cluster_template
cluster = objects.Cluster(self.context, **self.cluster_dict)
mock_driver.return_value = mesos_dr.Driver()
(template_path,
definition,
env_files) = cluster_conductor._extract_template_definition(
self.context, cluster)
env_files) = driver._extract_template_definition(self.context,
cluster)
expected = {
'ssh_key_name': 'keypair_id',
@ -176,8 +184,10 @@ class TestClusterConductorWithMesos(base.TestCase):
env_files)
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_with_lb(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid):
self.cluster_template_dict['master_lb_enabled'] = True
cluster_template = objects.ClusterTemplate(
@ -185,11 +195,12 @@ class TestClusterConductorWithMesos(base.TestCase):
mock_objects_cluster_template_get_by_uuid.return_value = \
cluster_template
cluster = objects.Cluster(self.context, **self.cluster_dict)
mock_driver.return_value = mesos_dr.Driver()
(template_path,
definition,
env_files) = cluster_conductor._extract_template_definition(
self.context, cluster)
env_files) = driver._extract_template_definition(self.context,
cluster)
expected = {
'ssh_key_name': 'keypair_id',
@ -227,8 +238,10 @@ class TestClusterConductorWithMesos(base.TestCase):
env_files)
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_multi_master(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid):
self.cluster_template_dict['master_lb_enabled'] = True
self.cluster_dict['master_count'] = 2
@ -237,11 +250,12 @@ class TestClusterConductorWithMesos(base.TestCase):
mock_objects_cluster_template_get_by_uuid.return_value = \
cluster_template
cluster = objects.Cluster(self.context, **self.cluster_dict)
mock_driver.return_value = mesos_dr.Driver()
(template_path,
definition,
env_files) = cluster_conductor._extract_template_definition(
self.context, cluster)
env_files) = driver._extract_template_definition(self.context,
cluster)
expected = {
'ssh_key_name': 'keypair_id',
@ -281,7 +295,8 @@ class TestClusterConductorWithMesos(base.TestCase):
@patch('magnum.conductor.utils.retrieve_cluster_template')
@patch('magnum.conf.CONF')
@patch('magnum.common.clients.OpenStackClients')
def setup_poll_test(self, mock_openstack_client, mock_conf,
@patch('magnum.drivers.common.driver.Driver.get_driver')
def setup_poll_test(self, mock_driver, mock_openstack_client, mock_conf,
mock_retrieve_cluster_template):
mock_conf.cluster_heat.max_attempts = 10
@ -290,10 +305,12 @@ class TestClusterConductorWithMesos(base.TestCase):
mock_heat_client = mock.MagicMock()
mock_heat_client.stacks.get.return_value = mock_heat_stack
mock_openstack_client.heat.return_value = mock_heat_client
mock_driver.return_value = mesos_dr.Driver()
cluster_template = objects.ClusterTemplate(
self.context, **self.cluster_template_dict)
mock_retrieve_cluster_template.return_value = cluster_template
poller = cluster_conductor.HeatPoller(mock_openstack_client, cluster)
poller = cluster_conductor.HeatPoller(mock_openstack_client, cluster,
mesos_dr.Driver())
poller.get_version_info = mock.MagicMock()
return (mock_heat_stack, cluster, poller)

View File

@ -18,6 +18,8 @@ from oslo_config import cfg
from oslo_service import loopingcall
from magnum.conductor.handlers import cluster_conductor
from magnum.drivers.common import driver
from magnum.drivers.swarm_fedora_atomic_v1 import driver as swarm_dr
from magnum import objects
from magnum.objects.fields import ClusterStatus as cluster_status
from magnum.tests import base
@ -81,8 +83,10 @@ class TestClusterConductorWithSwarm(base.TestCase):
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_all_values(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get):
cluster_template = objects.ClusterTemplate(
@ -94,12 +98,13 @@ class TestClusterConductorWithSwarm(base.TestCase):
mock_resp = mock.MagicMock()
mock_resp.text = expected_result
mock_get.return_value = mock_resp
mock_driver.return_value = swarm_dr.Driver()
cluster = objects.Cluster(self.context, **self.cluster_dict)
(template_path,
definition,
env_files) = cluster_conductor._extract_template_definition(
self.context, cluster)
env_files) = driver._extract_template_definition(self.context,
cluster)
expected = {
'ssh_key_name': 'keypair_id',
@ -141,8 +146,10 @@ class TestClusterConductorWithSwarm(base.TestCase):
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_with_registry(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get):
self.cluster_template_dict['registry_enabled'] = True
@ -155,6 +162,7 @@ class TestClusterConductorWithSwarm(base.TestCase):
mock_resp = mock.MagicMock()
mock_resp.text = expected_result
mock_get.return_value = mock_resp
mock_driver.return_value = swarm_dr.Driver()
cluster = objects.Cluster(self.context, **self.cluster_dict)
cfg.CONF.set_override('swift_region',
@ -163,8 +171,8 @@ class TestClusterConductorWithSwarm(base.TestCase):
(template_path,
definition,
env_files) = cluster_conductor._extract_template_definition(
self.context, cluster)
env_files) = driver._extract_template_definition(self.context,
cluster)
expected = {
'ssh_key_name': 'keypair_id',
@ -208,8 +216,10 @@ class TestClusterConductorWithSwarm(base.TestCase):
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_only_required(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get):
@ -231,12 +241,13 @@ class TestClusterConductorWithSwarm(base.TestCase):
mock_resp = mock.MagicMock()
mock_resp.text = expected_result
mock_get.return_value = mock_resp
mock_driver.return_value = swarm_dr.Driver()
cluster = objects.Cluster(self.context, **self.cluster_dict)
(template_path,
definition,
env_files) = cluster_conductor._extract_template_definition(
self.context, cluster)
env_files) = driver._extract_template_definition(self.context,
cluster)
expected = {
'ssh_key_name': 'keypair_id',
@ -267,8 +278,10 @@ class TestClusterConductorWithSwarm(base.TestCase):
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_with_lb(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get):
self.cluster_template_dict['master_lb_enabled'] = True
@ -281,12 +294,13 @@ class TestClusterConductorWithSwarm(base.TestCase):
mock_resp = mock.MagicMock()
mock_resp.text = expected_result
mock_get.return_value = mock_resp
mock_driver.return_value = swarm_dr.Driver()
cluster = objects.Cluster(self.context, **self.cluster_dict)
(template_path,
definition,
env_files) = cluster_conductor._extract_template_definition(
self.context, cluster)
env_files) = driver._extract_template_definition(self.context,
cluster)
expected = {
'ssh_key_name': 'keypair_id',
@ -328,8 +342,10 @@ class TestClusterConductorWithSwarm(base.TestCase):
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_multi_master(
self,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get):
self.cluster_template_dict['master_lb_enabled'] = True
@ -343,12 +359,13 @@ class TestClusterConductorWithSwarm(base.TestCase):
mock_resp = mock.MagicMock()
mock_resp.text = expected_result
mock_get.return_value = mock_resp
mock_driver.return_value = swarm_dr.Driver()
cluster = objects.Cluster(self.context, **self.cluster_dict)
(template_path,
definition,
env_files) = cluster_conductor._extract_template_definition(
self.context, cluster)
env_files) = driver._extract_template_definition(self.context,
cluster)
expected = {
'ssh_key_name': 'keypair_id',
@ -391,7 +408,8 @@ class TestClusterConductorWithSwarm(base.TestCase):
@patch('magnum.conductor.utils.retrieve_cluster_template')
@patch('magnum.conf.CONF')
@patch('magnum.common.clients.OpenStackClients')
def setup_poll_test(self, mock_openstack_client, mock_conf,
@patch('magnum.drivers.common.driver.Driver.get_driver')
def setup_poll_test(self, mock_driver, mock_openstack_client, mock_conf,
mock_retrieve_cluster_template):
mock_conf.cluster_heat.max_attempts = 10
@ -404,7 +422,9 @@ class TestClusterConductorWithSwarm(base.TestCase):
self.context, **self.cluster_template_dict)
mock_retrieve_cluster_template.return_value = \
cluster_template
poller = cluster_conductor.HeatPoller(mock_openstack_client, cluster)
mock_driver.return_value = swarm_dr.Driver()
poller = cluster_conductor.HeatPoller(mock_openstack_client, cluster,
swarm_dr.Driver())
poller.get_version_info = mock.MagicMock()
return (mock_heat_stack, cluster, poller)

View File

@ -19,11 +19,17 @@ import six
from magnum.common import exception
import magnum.conf
from magnum.drivers.common import driver
from magnum.drivers.common import template_def as cmn_tdef
from magnum.drivers.k8s_coreos_v1 import driver as k8s_coreos_dr
from magnum.drivers.k8s_coreos_v1 import template_def as k8s_coreos_tdef
from magnum.drivers.k8s_fedora_atomic_v1 import driver as k8sa_dr
from magnum.drivers.k8s_fedora_atomic_v1 import template_def as k8sa_tdef
from magnum.drivers.k8s_fedora_ironic_v1 import driver as k8s_i_dr
from magnum.drivers.k8s_fedora_ironic_v1 import template_def as k8si_tdef
from magnum.drivers.mesos_ubuntu_v1 import driver as mesos_dr
from magnum.drivers.mesos_ubuntu_v1 import template_def as mesos_tdef
from magnum.drivers.swarm_fedora_atomic_v1 import driver as swarm_dr
from magnum.drivers.swarm_fedora_atomic_v1 import template_def as swarm_tdef
from magnum.tests import base
@ -34,13 +40,13 @@ CONF = magnum.conf.CONF
class TemplateDefinitionTestCase(base.TestCase):
@mock.patch.object(cmn_tdef, 'iter_entry_points')
@mock.patch.object(driver, 'iter_entry_points')
def test_load_entry_points(self, mock_iter_entry_points):
mock_entry_point = mock.MagicMock()
mock_entry_points = [mock_entry_point]
mock_iter_entry_points.return_value = mock_entry_points.__iter__()
entry_points = cmn_tdef.TemplateDefinition.load_entry_points()
entry_points = driver.Driver().load_entry_points()
for (expected_entry_point,
(actual_entry_point, loaded_cls)) in zip(mock_entry_points,
@ -48,77 +54,64 @@ class TemplateDefinitionTestCase(base.TestCase):
self.assertEqual(expected_entry_point, actual_entry_point)
expected_entry_point.load.assert_called_once_with(require=False)
def test_get_template_definitions(self):
defs = cmn_tdef.TemplateDefinition.get_template_definitions()
vm_atomic_k8s = defs[('vm', 'fedora-atomic', 'kubernetes')]
vm_coreos_k8s = defs[('vm', 'coreos', 'kubernetes')]
self.assertEqual(1, len(vm_atomic_k8s))
self.assertEqual(k8sa_tdef.AtomicK8sTemplateDefinition,
vm_atomic_k8s['magnum_vm_atomic_k8s'])
self.assertEqual(1, len(vm_coreos_k8s))
self.assertEqual(k8s_coreos_tdef.CoreOSK8sTemplateDefinition,
vm_coreos_k8s['magnum_vm_coreos_k8s'])
def test_get_vm_atomic_kubernetes_definition(self):
definition = cmn_tdef.TemplateDefinition.get_template_definition(
'vm',
'fedora-atomic',
'kubernetes')
@mock.patch('magnum.drivers.common.driver.Driver.get_driver')
def test_get_vm_atomic_kubernetes_definition(self, mock_driver):
mock_driver.return_value = k8sa_dr.Driver()
cluster_driver = driver.Driver.get_driver('vm',
'fedora-atomic',
'kubernetes')
definition = cluster_driver.get_template_definition()
self.assertIsInstance(definition,
k8sa_tdef.AtomicK8sTemplateDefinition)
def test_get_bm_fedora_kubernetes_ironic_definition(self):
definition = cmn_tdef.TemplateDefinition.get_template_definition(
'bm',
'fedora',
'kubernetes')
@mock.patch('magnum.drivers.common.driver.Driver.get_driver')
def test_get_bm_fedora_kubernetes_ironic_definition(self, mock_driver):
mock_driver.return_value = k8s_i_dr.Driver()
cluster_driver = driver.Driver.get_driver('bm',
'fedora',
'kubernetes')
definition = cluster_driver.get_template_definition()
self.assertIsInstance(definition,
k8si_tdef.FedoraK8sIronicTemplateDefinition)
def test_get_vm_coreos_kubernetes_definition(self):
definition = cmn_tdef.TemplateDefinition.get_template_definition(
'vm',
'coreos',
'kubernetes')
@mock.patch('magnum.drivers.common.driver.Driver.get_driver')
def test_get_vm_coreos_kubernetes_definition(self, mock_driver):
mock_driver.return_value = k8s_coreos_dr.Driver()
cluster_driver = driver.Driver.get_driver('vm', 'coreos', 'kubernetes')
definition = cluster_driver.get_template_definition()
self.assertIsInstance(definition,
k8s_coreos_tdef.CoreOSK8sTemplateDefinition)
def test_get_vm_atomic_swarm_definition(self):
definition = cmn_tdef.TemplateDefinition.get_template_definition(
'vm',
'fedora-atomic',
'swarm')
@mock.patch('magnum.drivers.common.driver.Driver.get_driver')
def test_get_vm_atomic_swarm_definition(self, mock_driver):
mock_driver.return_value = swarm_dr.Driver()
cluster_driver = driver.Driver.get_driver('vm',
'fedora-atomic',
'swarm')
definition = cluster_driver.get_template_definition()
self.assertIsInstance(definition,
swarm_tdef.AtomicSwarmTemplateDefinition)
def test_get_vm_ubuntu_mesos_definition(self):
definition = cmn_tdef.TemplateDefinition.get_template_definition(
'vm',
'ubuntu',
'mesos')
@mock.patch('magnum.drivers.common.driver.Driver.get_driver')
def test_get_vm_ubuntu_mesos_definition(self, mock_driver):
mock_driver.return_value = mesos_dr.Driver()
cluster_driver = driver.Driver.get_driver('vm',
'ubuntu',
'mesos')
definition = cluster_driver.get_template_definition()
self.assertIsInstance(definition,
mesos_tdef.UbuntuMesosTemplateDefinition)
def test_get_definition_not_supported(self):
def test_get_driver_not_supported(self):
self.assertRaises(exception.ClusterTypeNotSupported,
cmn_tdef.TemplateDefinition.get_template_definition,
driver.Driver().get_driver,
'vm', 'not_supported', 'kubernetes')
def test_get_definition_not_enabled(self):
CONF.set_override('enabled_definitions',
['magnum_vm_atomic_k8s'],
group='cluster')
self.assertRaises(exception.ClusterTypeNotEnabled,
cmn_tdef.TemplateDefinition.get_template_definition,
'vm', 'coreos', 'kubernetes')
def test_required_param_not_set(self):
param = cmn_tdef.ParameterMapping('test', cluster_template_attr='test',
required=True)
@ -164,10 +157,7 @@ class TemplateDefinitionTestCase(base.TestCase):
self.assertIsNone(value)
def test_add_output_with_mapping_type(self):
definition = cmn_tdef.TemplateDefinition.get_template_definition(
'vm',
'fedora-atomic',
'kubernetes')
definition = k8sa_dr.Driver().get_template_definition()
mock_args = [1, 3, 4]
mock_kwargs = {'test': 'test'}
@ -227,11 +217,7 @@ class BaseTemplateDefinitionTestCase(base.TestCase):
class AtomicK8sTemplateDefinitionTestCase(BaseTemplateDefinitionTestCase):
def get_definition(self):
return cmn_tdef.TemplateDefinition.get_template_definition(
'vm',
'fedora-atomic',
'kubernetes',
)
return k8sa_dr.Driver().get_template_definition()
@mock.patch('magnum.common.clients.OpenStackClients')
@mock.patch('magnum.drivers.k8s_fedora_atomic_v1.template_def'
@ -446,12 +432,9 @@ class AtomicK8sTemplateDefinitionTestCase(BaseTemplateDefinitionTestCase):
k8sa_tdef.AtomicK8sTemplateDefinition().get_discovery_url,
fake_cluster)
def _test_update_outputs_api_address(self, coe, params, tls=True):
def _test_update_outputs_api_address(self, template_definition,
params, tls=True):
definition = cmn_tdef.TemplateDefinition.get_template_definition(
'vm',
'fedora-atomic',
coe)
expected_api_address = '%(protocol)s://%(address)s:%(port)s' % params
outputs = [
@ -465,8 +448,8 @@ class AtomicK8sTemplateDefinitionTestCase(BaseTemplateDefinitionTestCase):
mock_cluster_template = mock.MagicMock()
mock_cluster_template.tls_disabled = tls
definition.update_outputs(mock_stack, mock_cluster_template,
mock_cluster)
template_definition.update_outputs(mock_stack, mock_cluster_template,
mock_cluster)
self.assertEqual(expected_api_address, mock_cluster.api_address)
@ -479,7 +462,9 @@ class AtomicK8sTemplateDefinitionTestCase(BaseTemplateDefinitionTestCase):
'address': address,
'port': port,
}
self._test_update_outputs_api_address('kubernetes', params)
template_definition = k8sa_tdef.AtomicK8sTemplateDefinition()
self._test_update_outputs_api_address(template_definition, params)
def test_update_swarm_outputs_api_address(self):
address = 'updated_address'
@ -490,7 +475,9 @@ class AtomicK8sTemplateDefinitionTestCase(BaseTemplateDefinitionTestCase):
'address': address,
'port': port,
}
self._test_update_outputs_api_address('swarm', params)
template_definition = swarm_tdef.AtomicSwarmTemplateDefinition()
self._test_update_outputs_api_address(template_definition, params)
def test_update_k8s_outputs_if_cluster_template_is_secure(self):
address = 'updated_address'
@ -501,7 +488,9 @@ class AtomicK8sTemplateDefinitionTestCase(BaseTemplateDefinitionTestCase):
'address': address,
'port': port,
}
self._test_update_outputs_api_address('kubernetes', params, tls=False)
template_definition = k8sa_tdef.AtomicK8sTemplateDefinition()
self._test_update_outputs_api_address(template_definition, params,
tls=False)
def test_update_swarm_outputs_if_cluster_template_is_secure(self):
address = 'updated_address'
@ -512,14 +501,13 @@ class AtomicK8sTemplateDefinitionTestCase(BaseTemplateDefinitionTestCase):
'address': address,
'port': port,
}
self._test_update_outputs_api_address('swarm', params, tls=False)
def _test_update_outputs_none_api_address(self, coe, params, tls=True):
template_definition = swarm_tdef.AtomicSwarmTemplateDefinition()
self._test_update_outputs_api_address(template_definition, params,
tls=False)
definition = cmn_tdef.TemplateDefinition.get_template_definition(
'vm',
'fedora-atomic',
coe)
def _test_update_outputs_none_api_address(self, template_definition,
params, tls=True):
outputs = [
{"output_value": params['address'],
@ -533,8 +521,8 @@ class AtomicK8sTemplateDefinitionTestCase(BaseTemplateDefinitionTestCase):
mock_cluster_template = mock.MagicMock()
mock_cluster_template.tls_disabled = tls
definition.update_outputs(mock_stack, mock_cluster_template,
mock_cluster)
template_definition.update_outputs(mock_stack, mock_cluster_template,
mock_cluster)
self.assertEqual('none_api_address', mock_cluster.api_address)
@ -546,7 +534,9 @@ class AtomicK8sTemplateDefinitionTestCase(BaseTemplateDefinitionTestCase):
'address': None,
'port': port,
}
self._test_update_outputs_none_api_address('kubernetes', params)
template_definition = k8sa_tdef.AtomicK8sTemplateDefinition()
self._test_update_outputs_none_api_address(template_definition, params)
def test_update_swarm_outputs_none_api_address(self):
protocol = 'tcp'
@ -556,7 +546,8 @@ class AtomicK8sTemplateDefinitionTestCase(BaseTemplateDefinitionTestCase):
'address': None,
'port': port,
}
self._test_update_outputs_none_api_address('swarm', params)
template_definition = swarm_tdef.AtomicSwarmTemplateDefinition()
self._test_update_outputs_none_api_address(template_definition, params)
def test_update_outputs_master_address(self):
self._test_update_outputs_server_addrtess(
@ -592,11 +583,7 @@ class AtomicK8sTemplateDefinitionTestCase(BaseTemplateDefinitionTestCase):
class FedoraK8sIronicTemplateDefinitionTestCase(base.TestCase):
def get_definition(self):
return cmn_tdef.TemplateDefinition.get_template_definition(
'bm',
'fedora',
'kubernetes'
)
return k8s_i_dr.Driver().get_template_definition()
def assert_neutron_find(self, mock_neutron_v20_find,
osc, cluster_template):

View File

@ -58,12 +58,12 @@ oslo.config.opts =
oslo.config.opts.defaults =
magnum = magnum.common.config:set_cors_middleware_defaults
magnum.template_definitions =
magnum_bm_fedora_k8s = magnum.drivers.k8s_fedora_ironic_v1.template_def:FedoraK8sIronicTemplateDefinition
magnum_vm_atomic_k8s = magnum.drivers.k8s_fedora_atomic_v1.template_def:AtomicK8sTemplateDefinition
magnum_vm_coreos_k8s = magnum.drivers.k8s_coreos_v1.template_def:CoreOSK8sTemplateDefinition
magnum_vm_atomic_swarm = magnum.drivers.swarm_fedora_atomic_v1.template_def:AtomicSwarmTemplateDefinition
magnum_vm_ubuntu_mesos = magnum.drivers.mesos_ubuntu_v1.template_def:UbuntuMesosTemplateDefinition
magnum.drivers =
k8s_fedora_atomic_v1 = magnum.drivers.k8s_fedora_atomic_v1.driver:Driver
k8s_coreos_v1 = magnum.drivers.k8s_coreos_v1.driver:Driver
swarm_fedora_atomic_v1 = magnum.drivers.swarm_fedora_atomic_v1.driver:Driver
mesos_ubuntu_v1 = magnum.drivers.mesos_ubuntu_v1.driver:Driver
k8s_fedora_ironic_v1 = magnum.drivers.k8s_fedora_ironic_v1.driver:Driver
magnum.database.migration_backend =
sqlalchemy = magnum.db.sqlalchemy.migration