Browse Source

ng-3: Adapt existing drivers

The existing drivers are adapted to get node_count and master_count
information from the cluster's nodegroups. At the same time the
output mappings were updated to reflect the changes in the stack to
the nodegroups.

story: 2005266

Change-Id: I725413e77f5a7bdb48131e8a10e5dc884b5e066a
changes/09/642009/7
Theodoros Tsioutsias 3 years ago
parent
commit
ea95b0dc5c
  1. 31
      magnum/drivers/heat/driver.py
  2. 43
      magnum/drivers/heat/k8s_coreos_template_def.py
  3. 21
      magnum/drivers/heat/k8s_fedora_template_def.py
  4. 34
      magnum/drivers/heat/k8s_template_def.py
  5. 48
      magnum/drivers/heat/swarm_fedora_template_def.py
  6. 63
      magnum/drivers/heat/swarm_mode_template_def.py
  7. 188
      magnum/drivers/heat/template_def.py
  8. 45
      magnum/drivers/mesos_ubuntu_v1/template_def.py
  9. 8
      magnum/tests/unit/conductor/handlers/test_cluster_conductor.py
  10. 148
      magnum/tests/unit/conductor/handlers/test_k8s_cluster_conductor.py
  11. 92
      magnum/tests/unit/conductor/handlers/test_mesos_cluster_conductor.py
  12. 92
      magnum/tests/unit/conductor/handlers/test_swarm_cluster_conductor.py
  13. 57
      magnum/tests/unit/drivers/test_heat_driver.py
  14. 146
      magnum/tests/unit/drivers/test_template_definition.py

31
magnum/drivers/heat/driver.py

@ -164,11 +164,17 @@ class HeatDriver(driver.Driver):
rollback=False):
definition = self.get_template_definition()
osc = clients.OpenStackClients(context)
heat_params = {}
# stack node_count parameter name
stack_nc_param = definition.get_heat_param(cluster_attr='node_count')
heat_params[stack_nc_param] = cluster.node_count
# Find what changed checking the stack params
# against the ones in the template_def.
stack = osc.heat().stacks.get(cluster.stack_id,
resolve_outputs=True)
stack_params = stack.parameters
definition.add_nodegroup_params(cluster)
heat_params = definition.get_stack_diff(context, stack_params, cluster)
LOG.debug('Updating stack with these params: %s', heat_params)
scale_params = definition.get_scale_params(context,
cluster,
scale_manager)
@ -180,16 +186,22 @@ class HeatDriver(driver.Driver):
'disable_rollback': not rollback
}
osc = clients.OpenStackClients(context)
osc.heat().stacks.update(cluster.stack_id, **fields)
def _resize_stack(self, context, cluster, resize_manager,
node_count, nodes_to_remove, nodegroup=None,
rollback=False):
definition = self.get_template_definition()
heat_params = {}
stack_nc_param = definition.get_heat_param(cluster_attr='node_count')
heat_params[stack_nc_param] = node_count or cluster.node_count
osc = clients.OpenStackClients(context)
# Find what changed checking the stack params
# against the ones in the template_def.
stack = osc.heat().stacks.get(cluster.stack_id,
resolve_outputs=True)
stack_params = stack.parameters
definition.add_nodegroup_params(cluster)
heat_params = definition.get_stack_diff(context, stack_params, cluster)
LOG.debug('Updating stack with these params: %s', heat_params)
scale_params = definition.get_scale_params(context,
cluster,
@ -244,6 +256,8 @@ class HeatPoller(object):
self._sync_cluster_and_template_status(stack)
elif stack.stack_status != self.cluster.status:
self.template_def.update_outputs(stack, self.cluster_template,
self.cluster)
self._sync_cluster_status(stack)
if stack.stack_status in (fields.ClusterStatus.CREATE_FAILED,
@ -273,9 +287,6 @@ class HeatPoller(object):
def _sync_cluster_status(self, stack):
self.cluster.status = stack.stack_status
self.cluster.status_reason = stack.stack_status_reason
stack_nc_param = self.template_def.get_heat_param(
cluster_attr='node_count')
self.cluster.node_count = stack.parameters[stack_nc_param]
self.cluster.save()
def get_version_info(self, stack):

43
magnum/drivers/heat/k8s_coreos_template_def.py

@ -26,14 +26,16 @@ CONF = cfg.CONF
LOG = logging.getLogger(__name__)
class ServerAddressOutputMapping(template_def.OutputMapping):
class ServerAddressOutputMapping(template_def.NodeGroupOutputMapping):
public_ip_output_key = None
private_ip_output_key = None
def __init__(self, dummy_arg, cluster_attr=None):
self.cluster_attr = cluster_attr
def __init__(self, dummy_arg, nodegroup_attr=None, nodegroup_uuid=None):
self.nodegroup_attr = nodegroup_attr
self.nodegroup_uuid = nodegroup_uuid
self.heat_output = self.public_ip_output_key
self.is_stack_param = False
def set_output(self, stack, cluster_template, cluster):
if not cluster_template.floating_ip_enabled:
@ -63,12 +65,43 @@ class CoreOSK8sTemplateDefinition(k8s_template_def.K8sTemplateDefinition):
cluster_attr='docker_volume_size')
self.add_parameter('docker_storage_driver',
cluster_template_attr='docker_storage_driver')
def add_nodegroup_params(self, cluster):
super(CoreOSK8sTemplateDefinition,
self).add_nodegroup_params(cluster)
worker_ng = cluster.default_ng_worker
master_ng = cluster.default_ng_master
self.add_parameter('number_of_minions',
nodegroup_attr='node_count',
nodegroup_uuid=worker_ng.uuid,
param_class=template_def.NodeGroupParameterMapping)
self.add_parameter('minion_flavor',
nodegroup_attr='flavor_id',
nodegroup_uuid=worker_ng.uuid,
param_class=template_def.NodeGroupParameterMapping)
self.add_parameter('master_flavor',
nodegroup_attr='flavor_id',
nodegroup_uuid=master_ng.uuid,
param_class=template_def.NodeGroupParameterMapping)
def update_outputs(self, stack, cluster_template, cluster):
worker_ng = cluster.default_ng_worker
master_ng = cluster.default_ng_master
self.add_output('kube_minions',
cluster_attr='node_addresses',
nodegroup_attr='node_addresses',
nodegroup_uuid=worker_ng.uuid,
mapping_type=NodeAddressOutputMapping)
self.add_output('kube_masters',
cluster_attr='master_addresses',
nodegroup_attr='node_addresses',
nodegroup_uuid=master_ng.uuid,
mapping_type=MasterAddressOutputMapping)
self.add_output('number_of_minions',
nodegroup_attr='node_count',
nodegroup_uuid=worker_ng.uuid,
is_stack_param=True)
super(CoreOSK8sTemplateDefinition,
self).update_outputs(stack, cluster_template, cluster)
def get_params(self, context, cluster_template, cluster, **kwargs):
extra_params = kwargs.pop('extra_params', {})

21
magnum/drivers/heat/k8s_fedora_template_def.py

@ -27,14 +27,16 @@ CONF = cfg.CONF
LOG = logging.getLogger(__name__)
class ServerAddressOutputMapping(template_def.OutputMapping):
class ServerAddressOutputMapping(template_def.NodeGroupOutputMapping):
public_ip_output_key = None
private_ip_output_key = None
def __init__(self, dummy_arg, cluster_attr=None):
self.cluster_attr = cluster_attr
def __init__(self, dummy_arg, nodegroup_attr=None, nodegroup_uuid=None):
self.nodegroup_attr = nodegroup_attr
self.nodegroup_uuid = nodegroup_uuid
self.heat_output = self.public_ip_output_key
self.is_stack_param = False
def set_output(self, stack, cluster_template, cluster):
if not cluster_template.floating_ip_enabled:
@ -64,12 +66,21 @@ class K8sFedoraTemplateDefinition(k8s_template_def.K8sTemplateDefinition):
cluster_attr='docker_volume_size')
self.add_parameter('docker_storage_driver',
cluster_template_attr='docker_storage_driver')
def update_outputs(self, stack, cluster_template, cluster):
worker_ng = cluster.default_ng_worker
master_ng = cluster.default_ng_master
self.add_output('kube_minions',
cluster_attr='node_addresses',
nodegroup_attr='node_addresses',
nodegroup_uuid=worker_ng.uuid,
mapping_type=NodeAddressOutputMapping)
self.add_output('kube_masters',
cluster_attr='master_addresses',
nodegroup_attr='node_addresses',
nodegroup_uuid=master_ng.uuid,
mapping_type=MasterAddressOutputMapping)
super(K8sFedoraTemplateDefinition,
self).update_outputs(stack, cluster_template, cluster)
def get_params(self, context, cluster_template, cluster, **kwargs):
extra_params = kwargs.pop('extra_params', {})

34
magnum/drivers/heat/k8s_template_def.py

@ -55,12 +55,6 @@ class K8sTemplateDefinition(template_def.BaseTemplateDefinition):
def __init__(self):
super(K8sTemplateDefinition, self).__init__()
self.add_parameter('master_flavor',
cluster_attr='master_flavor_id')
self.add_parameter('minion_flavor',
cluster_attr='flavor_id')
self.add_parameter('number_of_minions',
cluster_attr='node_count')
self.add_parameter('external_network',
cluster_template_attr='external_network_id',
required=True)
@ -93,6 +87,34 @@ class K8sTemplateDefinition(template_def.BaseTemplateDefinition):
self.add_output('kube_masters_private',
cluster_attr=None)
def add_nodegroup_params(self, cluster):
super(K8sTemplateDefinition,
self).add_nodegroup_params(cluster)
worker_ng = cluster.default_ng_worker
master_ng = cluster.default_ng_master
self.add_parameter('number_of_minions',
nodegroup_attr='node_count',
nodegroup_uuid=worker_ng.uuid,
param_class=template_def.NodeGroupParameterMapping)
self.add_parameter('minion_flavor',
nodegroup_attr='flavor_id',
nodegroup_uuid=worker_ng.uuid,
param_class=template_def.NodeGroupParameterMapping)
self.add_parameter('master_flavor',
nodegroup_attr='flavor_id',
nodegroup_uuid=master_ng.uuid,
param_class=template_def.NodeGroupParameterMapping)
def update_outputs(self, stack, cluster_template, cluster):
worker_ng = cluster.default_ng_worker
self.add_output('number_of_minions',
nodegroup_attr='node_count',
nodegroup_uuid=worker_ng.uuid,
is_stack_param=True,
mapping_type=template_def.NodeGroupOutputMapping)
super(K8sTemplateDefinition,
self).update_outputs(stack, cluster_template, cluster)
def get_params(self, context, cluster_template, cluster, **kwargs):
extra_params = kwargs.pop('extra_params', {})

48
magnum/drivers/heat/swarm_fedora_template_def.py

@ -45,12 +45,6 @@ class SwarmFedoraTemplateDefinition(template_def.BaseTemplateDefinition):
self.add_parameter('cluster_uuid',
cluster_attr='uuid',
param_type=str)
self.add_parameter('number_of_nodes',
cluster_attr='node_count')
self.add_parameter('master_flavor',
cluster_attr='master_flavor_id')
self.add_parameter('node_flavor',
cluster_attr='flavor_id')
self.add_parameter('docker_volume_size',
cluster_attr='docker_volume_size')
self.add_parameter('volume_driver',
@ -79,15 +73,49 @@ class SwarmFedoraTemplateDefinition(template_def.BaseTemplateDefinition):
mapping_type=SwarmApiAddressOutputMapping)
self.add_output('swarm_master_private',
cluster_attr=None)
self.add_output('swarm_masters',
cluster_attr='master_addresses')
self.add_output('swarm_nodes_private',
cluster_attr=None)
self.add_output('swarm_nodes',
cluster_attr='node_addresses')
self.add_output('discovery_url',
cluster_attr='discovery_url')
def add_nodegroup_params(self, cluster):
super(SwarmFedoraTemplateDefinition,
self).add_nodegroup_params(cluster)
master_ng = cluster.default_ng_master
worker_ng = cluster.default_ng_worker
self.add_parameter('number_of_nodes',
nodegroup_attr='node_count',
nodegroup_uuid=worker_ng.uuid,
param_class=template_def.NodeGroupParameterMapping)
self.add_parameter('node_flavor',
nodegroup_attr='flavor_id',
nodegroup_uuid=worker_ng.uuid,
param_class=template_def.NodeGroupParameterMapping)
self.add_parameter('master_flavor',
nodegroup_attr='flavor_id',
nodegroup_uuid=master_ng.uuid,
param_class=template_def.NodeGroupParameterMapping)
def update_outputs(self, stack, cluster_template, cluster):
worker_ng = cluster.default_ng_worker
master_ng = cluster.default_ng_master
self.add_output('swarm_masters',
nodegroup_attr='node_addresses',
nodegroup_uuid=master_ng.uuid,
mapping_type=template_def.NodeGroupOutputMapping)
self.add_output('swarm_nodes',
nodegroup_attr='node_addresses',
nodegroup_uuid=worker_ng.uuid,
mapping_type=template_def.NodeGroupOutputMapping)
self.add_output('number_of_nodes',
nodegroup_attr='node_count',
nodegroup_uuid=worker_ng.uuid,
is_stack_param=True,
mapping_type=template_def.NodeGroupOutputMapping)
super(SwarmFedoraTemplateDefinition,
self).update_outputs(stack, cluster_template, cluster)
def get_params(self, context, cluster_template, cluster, **kwargs):
extra_params = kwargs.pop('extra_params', {})
extra_params['discovery_url'] = \

63
magnum/drivers/heat/swarm_mode_template_def.py

@ -39,13 +39,15 @@ class SwarmModeApiAddressOutputMapping(template_def.OutputMapping):
setattr(cluster, self.cluster_attr, value)
class ServerAddressOutputMapping(template_def.OutputMapping):
class ServerAddressOutputMapping(template_def.NodeGroupOutputMapping):
public_ip_output_key = None
private_ip_output_key = None
def __init__(self, dummy_arg, cluster_attr=None):
self.cluster_attr = cluster_attr
def __init__(self, dummy_arg, nodegroup_attr=None, nodegroup_uuid=None):
self.heat_output = self.public_ip_output_key
self.nodegroup_attr = nodegroup_attr
self.nodegroup_uuid = nodegroup_uuid
self.is_stack_param = False
class MasterAddressOutputMapping(ServerAddressOutputMapping):
@ -63,7 +65,10 @@ class MasterAddressOutputMapping(ServerAddressOutputMapping):
for output in stack.to_dict().get('outputs', []):
if output['output_key'] in self.heat_output:
_master_addresses += output['output_value']
setattr(cluster, self.cluster_attr, _master_addresses)
for ng in cluster.nodegroups:
if ng.uuid == self.nodegroup_uuid:
setattr(ng, self.nodegroup_attr, _master_addresses)
class NodeAddressOutputMapping(ServerAddressOutputMapping):
@ -87,12 +92,6 @@ class SwarmModeTemplateDefinition(template_def.BaseTemplateDefinition):
self.add_parameter('cluster_uuid',
cluster_attr='uuid',
param_type=str)
self.add_parameter('number_of_nodes',
cluster_attr='node_count')
self.add_parameter('master_flavor',
cluster_attr='master_flavor_id')
self.add_parameter('node_flavor',
cluster_attr='flavor_id')
self.add_parameter('docker_volume_size',
cluster_attr='docker_volume_size')
self.add_parameter('volume_driver',
@ -113,12 +112,6 @@ class SwarmModeTemplateDefinition(template_def.BaseTemplateDefinition):
self.add_output('api_address',
cluster_attr='api_address',
mapping_type=SwarmModeApiAddressOutputMapping)
self.add_output('swarm_masters',
cluster_attr='master_addresses',
mapping_type=MasterAddressOutputMapping)
self.add_output('swarm_nodes',
cluster_attr='node_addresses',
mapping_type=NodeAddressOutputMapping)
def get_params(self, context, cluster_template, cluster, **kwargs):
extra_params = kwargs.pop('extra_params', {})
@ -148,6 +141,44 @@ class SwarmModeTemplateDefinition(template_def.BaseTemplateDefinition):
extra_params=extra_params,
**kwargs)
def add_nodegroup_params(self, cluster):
super(SwarmModeTemplateDefinition,
self).add_nodegroup_params(cluster)
worker_ng = cluster.default_ng_worker
master_ng = cluster.default_ng_master
self.add_parameter('number_of_nodes',
nodegroup_attr='node_count',
nodegroup_uuid=worker_ng.uuid,
param_class=template_def.NodeGroupParameterMapping)
self.add_parameter('node_flavor',
nodegroup_attr='flavor_id',
nodegroup_uuid=worker_ng.uuid,
param_class=template_def.NodeGroupParameterMapping)
self.add_parameter('master_flavor',
nodegroup_attr='flavor_id',
nodegroup_uuid=master_ng.uuid,
param_class=template_def.NodeGroupParameterMapping)
def update_outputs(self, stack, cluster_template, cluster):
worker_ng = cluster.default_ng_worker
master_ng = cluster.default_ng_master
self.add_output('swarm_masters',
nodegroup_attr='node_addresses',
nodegroup_uuid=master_ng.uuid,
mapping_type=MasterAddressOutputMapping)
self.add_output('swarm_nodes',
nodegroup_attr='node_addresses',
nodegroup_uuid=worker_ng.uuid,
mapping_type=NodeAddressOutputMapping)
self.add_output('number_of_nodes',
nodegroup_attr='node_count',
nodegroup_uuid=worker_ng.uuid,
is_stack_param=True,
mapping_type=template_def.NodeGroupOutputMapping)
super(SwarmModeTemplateDefinition,
self).update_outputs(stack, cluster_template, cluster)
def get_env_files(self, cluster_template, cluster):
env_files = []

188
magnum/drivers/heat/template_def.py

@ -16,6 +16,7 @@ import ast
from oslo_log import log as logging
from oslo_utils import strutils
from oslo_utils import uuidutils
import re
import requests
import six
@ -51,8 +52,7 @@ class ParameterMapping(object):
isn't set, a RequiredArgumentNotProvided exception will be raised.
"""
def __init__(self, heat_param, cluster_template_attr=None,
cluster_attr=None, required=False,
param_type=lambda x: x):
cluster_attr=None, required=False, param_type=lambda x: x):
self.heat_param = heat_param
self.cluster_template_attr = cluster_template_attr
self.cluster_attr = cluster_attr
@ -60,8 +60,17 @@ class ParameterMapping(object):
self.param_type = param_type
def set_param(self, params, cluster_template, cluster):
value = None
value = self.get_value(cluster_template, cluster)
if self.required and value is None:
kwargs = dict(heat_param=self.heat_param)
raise exception.RequiredParameterNotProvided(**kwargs)
if value is not None:
value = self.param_type(value)
params[self.heat_param] = value
def get_value(self, cluster_template, cluster):
value = None
if (self.cluster_template_attr and
getattr(cluster_template, self.cluster_template_attr, None)
is not None):
@ -69,13 +78,26 @@ class ParameterMapping(object):
elif (self.cluster_attr and
getattr(cluster, self.cluster_attr, None) is not None):
value = getattr(cluster, self.cluster_attr)
elif self.required:
kwargs = dict(heat_param=self.heat_param)
raise exception.RequiredParameterNotProvided(**kwargs)
return value
if value is not None:
value = self.param_type(value)
params[self.heat_param] = value
class NodeGroupParameterMapping(ParameterMapping):
def __init__(self, heat_param, nodegroup_attr=None, nodegroup_uuid=None,
required=False, param_type=lambda x: x):
self.heat_param = heat_param
self.nodegroup_attr = nodegroup_attr
self.nodegroup_uuid = nodegroup_uuid
self.required = required
self.param_type = param_type
def get_value(self, cluster_template, cluster):
value = None
for ng in cluster.nodegroups:
if ng.uuid == self.nodegroup_uuid:
value = getattr(ng, self.nodegroup_attr)
break
return value
class OutputMapping(object):
@ -94,8 +116,9 @@ class OutputMapping(object):
return
output_value = self.get_output_value(stack)
if output_value is not None:
setattr(cluster, self.cluster_attr, output_value)
if output_value is None:
return
setattr(cluster, self.cluster_attr, output_value)
def matched(self, output_key):
return self.heat_output == output_key
@ -109,6 +132,51 @@ class OutputMapping(object):
return None
class NodeGroupOutputMapping(OutputMapping):
"""A mapping associating stack info and nodegroup attr.
A NodeGroupOutputMapping is an association of a Heat output or parameter
with a nodegroup field. By default stack output values are reflected to the
specified nodegroup attribute. In the case where is_stack_param is set to
True, the specified heat information will come from the stack parameters.
"""
def __init__(self, heat_output, nodegroup_attr=None, nodegroup_uuid=None,
is_stack_param=False):
self.nodegroup_attr = nodegroup_attr
self.nodegroup_uuid = nodegroup_uuid
self.heat_output = heat_output
self.is_stack_param = is_stack_param
def set_output(self, stack, cluster_template, cluster):
if self.nodegroup_attr is None:
return
output_value = self.get_output_value(stack)
if output_value is None:
return
for ng in cluster.nodegroups:
if ng.uuid == self.nodegroup_uuid:
# nodegroups are fetched from the database every
# time, so the bad thing here is that we need to
# save each change.
setattr(ng, self.nodegroup_attr, output_value)
ng.save()
def get_output_value(self, stack):
if not self.is_stack_param:
return super(NodeGroupOutputMapping, self).get_output_value(stack)
return self.get_param_value(stack)
def get_param_value(self, stack):
for param, value in stack.parameters.items():
if param == self.heat_output:
return value
LOG.warning('stack does not have param %s', self.heat_output)
return None
@six.add_metaclass(abc.ABCMeta)
class TemplateDefinition(object):
"""A mapping between Magnum objects and Heat templates.
@ -123,7 +191,8 @@ class TemplateDefinition(object):
self.output_mappings = list()
def add_parameter(self, *args, **kwargs):
param = ParameterMapping(*args, **kwargs)
param_class = kwargs.pop('param_class', ParameterMapping)
param = param_class(*args, **kwargs)
self.param_mappings.append(param)
def add_output(self, *args, **kwargs):
@ -171,7 +240,8 @@ class TemplateDefinition(object):
"""
return []
def get_heat_param(self, cluster_attr=None, cluster_template_attr=None):
def get_heat_param(self, cluster_attr=None, cluster_template_attr=None,
nodegroup_attr=None, nodegroup_uuid=None):
"""Returns stack param name.
Return stack param name using cluster and cluster_template attributes
@ -183,12 +253,53 @@ class TemplateDefinition(object):
:return: stack parameter name or None
"""
for mapping in self.param_mappings:
if (mapping.cluster_attr == cluster_attr and
mapping.cluster_template_attr == cluster_template_attr):
return mapping.heat_param
if hasattr(mapping, 'cluster_attr'):
if mapping.cluster_attr == cluster_attr and \
mapping.cluster_template_attr == cluster_template_attr:
return mapping.heat_param
if hasattr(mapping, 'nodegroup_attr'):
if mapping.nodegroup_attr == nodegroup_attr and \
mapping.nodegroup_uuid == nodegroup_uuid:
return mapping.heat_param
return None
def get_stack_diff(self, context, heat_params, cluster):
"""Returns all the params that are changed.
Compares the current params of a stack with the template def for
the cluster and return the ones that changed.
:param heat_params: a dict containing the current params and values
for a stack
:param cluster: the cluster we need to compare with.
"""
diff = {}
for mapping in self.param_mappings:
try:
heat_param_name = mapping.heat_param
stack_value = heat_params[heat_param_name]
value = mapping.get_value(cluster.cluster_template, cluster)
if value is None:
continue
# We need to avoid changing the param values if it's not
# necessary, so for some attributes we need to resolve the
# value either to name or uuid.
value = self.resolve_ambiguous_values(context, heat_param_name,
stack_value, value)
if stack_value != value:
diff.update({heat_param_name: value})
except KeyError:
# If the key is not in heat_params just skip it. In case
# of update we don't want to trigger a rebuild....
continue
return diff
def resolve_ambiguous_values(self, context, heat_param, heat_value, value):
return str(value)
def add_nodegroup_params(self, cluster):
pass
def update_outputs(self, stack, cluster_template, cluster):
for output in self.output_mappings:
output.set_output(stack, cluster_template, cluster)
@ -224,8 +335,6 @@ class BaseTemplateDefinition(TemplateDefinition):
cluster_template_attr='https_proxy')
self.add_parameter('no_proxy',
cluster_template_attr='no_proxy')
self.add_parameter('number_of_masters',
cluster_attr='master_count')
@property
def driver_module_path(self):
@ -243,6 +352,9 @@ class BaseTemplateDefinition(TemplateDefinition):
def get_params(self, context, cluster_template, cluster, **kwargs):
osc = self.get_osc(context)
# Add all the params from the cluster's nodegroups
self.add_nodegroup_params(cluster)
extra_params = kwargs.pop('extra_params', {})
extra_params['trustee_domain_id'] = osc.keystone().trustee_domain_id
extra_params['trustee_user_id'] = cluster.trustee_user_id
@ -271,6 +383,39 @@ class BaseTemplateDefinition(TemplateDefinition):
extra_params=extra_params,
**kwargs)
def resolve_ambiguous_values(self, context, heat_param, heat_value, value):
# Ambiguous values should be converted to the same format.
osc = self.get_osc(context)
if heat_param == 'external_network':
network = osc.neutron().show_network(heat_value).get('network')
if uuidutils.is_uuid_like(heat_value):
value = network.get('id')
else:
value = network('name')
# Any other values we might need to resolve?
return super(BaseTemplateDefinition, self).resolve_ambiguous_values(
context, heat_param, heat_value, value)
def add_nodegroup_params(self, cluster):
# Assuming that all the drivers that will not override
# this method do not support more than two nodegroups.
# Meaning that we have one master and one worker.
master_ng = cluster.default_ng_master
self.add_parameter('number_of_masters',
nodegroup_attr='node_count',
nodegroup_uuid=master_ng.uuid,
param_class=NodeGroupParameterMapping)
def update_outputs(self, stack, cluster_template, cluster):
master_ng = cluster.default_ng_master
self.add_output('number_of_masters',
nodegroup_attr='node_count',
nodegroup_uuid=master_ng.uuid,
is_stack_param=True,
mapping_type=NodeGroupOutputMapping)
super(BaseTemplateDefinition,
self).update_outputs(stack, cluster_template, cluster)
def validate_discovery_url(self, discovery_url, expect_size):
url = str(discovery_url)
if url[len(url)-1] == '/':
@ -327,11 +472,8 @@ class BaseTemplateDefinition(TemplateDefinition):
def get_discovery_url(self, cluster, cluster_template=None):
if hasattr(cluster, 'discovery_url') and cluster.discovery_url:
if getattr(cluster, 'master_count', None) is not None:
self.validate_discovery_url(cluster.discovery_url,
cluster.master_count)
else:
self.validate_discovery_url(cluster.discovery_url, 1)
self.validate_discovery_url(cluster.discovery_url,
cluster.master_count)
discovery_url = cluster.discovery_url
else:
discovery_endpoint = (

45
magnum/drivers/mesos_ubuntu_v1/template_def.py

@ -31,12 +31,6 @@ class UbuntuMesosTemplateDefinition(template_def.BaseTemplateDefinition):
cluster_template_attr='fixed_network')
self.add_parameter('fixed_subnet',
cluster_template_attr='fixed_subnet')
self.add_parameter('number_of_slaves',
cluster_attr='node_count')
self.add_parameter('master_flavor',
cluster_attr='master_flavor_id')
self.add_parameter('slave_flavor',
cluster_attr='flavor_id')
self.add_parameter('cluster_name',
cluster_attr='name')
self.add_parameter('volume_driver',
@ -46,12 +40,45 @@ class UbuntuMesosTemplateDefinition(template_def.BaseTemplateDefinition):
cluster_attr='api_address')
self.add_output('mesos_master_private',
cluster_attr=None)
self.add_output('mesos_master',
cluster_attr='master_addresses')
self.add_output('mesos_slaves_private',
cluster_attr=None)
def add_nodegroup_params(self, cluster):
super(UbuntuMesosTemplateDefinition,
self).add_nodegroup_params(cluster)
master_ng = cluster.default_ng_master
worker_ng = cluster.default_ng_worker
self.add_parameter('number_of_slaves',
nodegroup_attr='node_count',
nodegroup_uuid=worker_ng.uuid,
param_class=template_def.NodeGroupParameterMapping)
self.add_parameter('slave_flavor',
nodegroup_attr='flavor_id',
nodegroup_uuid=worker_ng.uuid,
param_class=template_def.NodeGroupParameterMapping)
self.add_parameter('master_flavor',
nodegroup_attr='flavor_id',
nodegroup_uuid=master_ng.uuid,
param_class=template_def.NodeGroupParameterMapping)
def update_outputs(self, stack, cluster_template, cluster):
worker_ng = cluster.default_ng_worker
master_ng = cluster.default_ng_master
self.add_output('mesos_master',
nodegroup_attr='node_addresses',
nodegroup_uuid=master_ng.uuid,
mapping_type=template_def.NodeGroupOutputMapping)
self.add_output('mesos_slaves',
cluster_attr='node_addresses')
nodegroup_attr='node_addresses',
nodegroup_uuid=worker_ng.uuid,
mapping_type=template_def.NodeGroupOutputMapping)
self.add_output('number_of_slaves',
nodegroup_attr='node_count',
nodegroup_uuid=worker_ng.uuid,
is_stack_param=True,
mapping_type=template_def.NodeGroupOutputMapping)
super(UbuntuMesosTemplateDefinition,
self).update_outputs(stack, cluster_template, cluster)
def get_params(self, context, cluster_template, cluster, **kwargs):
extra_params = kwargs.pop('extra_params', {})

8
magnum/tests/unit/conductor/handlers/test_cluster_conductor.py

@ -121,8 +121,8 @@ class TestHandler(db_base.DbTestCase):
taxonomy.OUTCOME_FAILURE, notifications[0].payload['outcome'])
cluster = objects.Cluster.get(self.context, self.cluster.uuid)
self.assertEqual(1, cluster.node_count)
self.assertEqual(1, self.worker.node_count)
self.assertEqual(1, cluster.node_count)
@patch('magnum.conductor.scale_manager.get_scale_manager')
@patch('magnum.drivers.common.driver.Driver.get_driver')
@ -218,8 +218,8 @@ class TestHandler(db_base.DbTestCase):
# created and the previous solution seems kind of hacky.
cluster_dict = utils.get_test_cluster(node_count=1)
cluster = objects.Cluster(self.context, **cluster_dict)
node_count = cluster.node_count
master_count = cluster.node_count
node_count = 1
master_count = 1
del cluster_dict['id']
del cluster_dict['uuid']
cluster_obj = objects.Cluster(self.context, **cluster_dict)
@ -242,6 +242,8 @@ class TestHandler(db_base.DbTestCase):
mock_trust_manager.create_trustee_and_trust.assert_called_once_with(
osc, cluster)
self.assertEqual(2, len(cluster.nodegroups))
self.assertEqual(node_count, cluster.node_count)
self.assertEqual(master_count, cluster.master_count)
self.assertEqual(node_count, cluster.default_ng_worker.node_count)
self.assertEqual(master_count, cluster.default_ng_master.node_count)

148
magnum/tests/unit/conductor/handlers/test_k8s_cluster_conductor.py

@ -114,6 +114,38 @@ class TestClusterConductorWithK8s(base.TestCase):
'flavor_id': 'flavor_id',
'project_id': 'project_id',
}
self.worker_ng_dict = {
'uuid': '5d12f6fd-a196-4bf0-ae4c-1f639a523a53',
'name': 'worker_ng',
'cluster_id': '5d12f6fd-a196-4bf0-ae4c-1f639a523a52',
'project_id': 'project_id',
'docker_volume_size': 20,
'labels': self.cluster_dict['labels'],
'flavor_id': 'flavor_id',
'image_id': 'image_id',
'node_addresses': ['172.17.2.4'],
'node_count': 1,
'role': 'worker',
'max_nodes': 5,
'min_nodes': 1,
'is_default': True
}
self.master_ng_dict = {
'uuid': '5d12f6fd-a196-4bf0-ae4c-1f639a523a54',
'name': 'master_ng',
'cluster_id': '5d12f6fd-a196-4bf0-ae4c-1f639a523a52',
'project_id': 'project_id',
'docker_volume_size': 20,
'labels': self.cluster_dict['labels'],
'flavor_id': 'master_flavor_id',
'image_id': 'image_id',
'node_addresses': ['172.17.2.18'],
'node_count': 1,
'role': 'master',
'max_nodes': 5,
'min_nodes': 1,
'is_default': True
}
self.context.user_name = 'fake_user'
self.context.project_id = 'fake_tenant'
osc_patcher = mock.patch('magnum.common.clients.OpenStackClients')
@ -137,6 +169,7 @@ class TestClusterConductorWithK8s(base.TestCase):
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.objects.NodeGroup.list')
@patch('magnum.drivers.common.driver.Driver.get_driver')
@patch('magnum.conductor.handlers.common.cert_manager'
'.sign_node_certificate')
@ -146,11 +179,13 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_generate_csr_and_key,
mock_sign_node_certificate,
mock_driver,
mock_objects_nodegroup_list,
mock_objects_cluster_template_get_by_uuid,
mock_get):
self._test_extract_template_definition(
mock_generate_csr_and_key, mock_sign_node_certificate,
mock_driver, mock_objects_cluster_template_get_by_uuid, mock_get)
mock_driver, mock_objects_cluster_template_get_by_uuid, mock_get,
mock_objects_nodegroup_list)
def _test_extract_template_definition(
self,
@ -159,11 +194,16 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get,
mock_objects_nodegroup_list,
missing_attr=None):
if missing_attr in self.cluster_template_dict:
self.cluster_template_dict[missing_attr] = None
elif missing_attr in self.cluster_dict:
self.cluster_dict[missing_attr] = None
elif missing_attr == 'node_count':
self.worker_ng_dict['node_count'] = None
elif missing_attr == 'master_count':
self.master_ng_dict['node_count'] = None
cluster_template = objects.ClusterTemplate(
self.context, **self.cluster_template_dict)
mock_generate_csr_and_key.return_value = {'csr': 'csr',
@ -179,6 +219,9 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_resp.status_code = 200
mock_get.return_value = mock_resp
cluster = objects.Cluster(self.context, **self.cluster_dict)
worker_ng = objects.NodeGroup(self.context, **self.worker_ng_dict)
master_ng = objects.NodeGroup(self.context, **self.master_ng_dict)
mock_objects_nodegroup_list.return_value = [master_ng, worker_ng]
mock_driver.return_value = k8s_dr.Driver()
(template_path,
@ -310,6 +353,7 @@ class TestClusterConductorWithK8s(base.TestCase):
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.objects.NodeGroup.list')
@patch('magnum.drivers.common.driver.Driver.get_driver')
@patch('magnum.conductor.handlers.common.cert_manager'
'.sign_node_certificate')
@ -319,6 +363,7 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_generate_csr_and_key,
mock_sign_node_certificate,
mock_driver,
mock_objects_nodegroup_list,
mock_objects_cluster_template_get_by_uuid,
mock_get):
self.cluster_template_dict['registry_enabled'] = True
@ -336,6 +381,9 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_resp.text = expected_result
mock_get.return_value = mock_resp
cluster = objects.Cluster(self.context, **self.cluster_dict)
worker_ng = objects.NodeGroup(self.context, **self.worker_ng_dict)
master_ng = objects.NodeGroup(self.context, **self.master_ng_dict)
mock_objects_nodegroup_list.return_value = [master_ng, worker_ng]
mock_driver.return_value = k8s_dr.Driver()
CONF.set_override('swift_region',
@ -431,6 +479,7 @@ class TestClusterConductorWithK8s(base.TestCase):
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.objects.NodeGroup.list')
@patch('magnum.drivers.common.driver.Driver.get_driver')
@patch('magnum.conductor.handlers.common.cert_manager'
'.sign_node_certificate')
@ -440,6 +489,7 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_generate_csr_and_key,
mock_sign_node_certificate,
mock_driver,
mock_objects_nodegroup_list,
mock_objects_cluster_template_get_by_uuid,
mock_get):
@ -467,6 +517,9 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_get.return_value = mock_resp
mock_driver.return_value = k8s_dr.Driver()
cluster = objects.Cluster(self.context, **self.cluster_dict)
worker_ng = objects.NodeGroup(self.context, **self.worker_ng_dict)
master_ng = objects.NodeGroup(self.context, **self.master_ng_dict)
mock_objects_nodegroup_list.return_value = [master_ng, worker_ng]
(template_path,
definition,
@ -540,10 +593,12 @@ class TestClusterConductorWithK8s(base.TestCase):
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.objects.NodeGroup.list')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_coreos_with_disovery(
self,
mock_driver,
mock_objects_nodegroup_list,
mock_objects_cluster_template_get_by_uuid,
mock_get):
self.cluster_template_dict['cluster_distro'] = 'coreos'
@ -558,6 +613,9 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_resp.status_code = 200
mock_get.return_value = mock_resp
cluster = objects.Cluster(self.context, **self.cluster_dict)
worker_ng = objects.NodeGroup(self.context, **self.worker_ng_dict)
master_ng = objects.NodeGroup(self.context, **self.master_ng_dict)
mock_objects_nodegroup_list.return_value = [master_ng, worker_ng]
mock_driver.return_value = k8s_coreos_dr.Driver()
(template_path,
@ -640,10 +698,12 @@ class TestClusterConductorWithK8s(base.TestCase):
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.objects.NodeGroup.list')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_coreos_no_discoveryurl(
self,
mock_driver,
mock_objects_nodegroup_list,
mock_objects_cluster_template_get_by_uuid,
reqget):
self.cluster_template_dict['cluster_distro'] = 'coreos'
@ -656,6 +716,9 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_objects_cluster_template_get_by_uuid.return_value = \
cluster_template
cluster = objects.Cluster(self.context, **self.cluster_dict)
worker_ng = objects.NodeGroup(self.context, **self.worker_ng_dict)
master_ng = objects.NodeGroup(self.context, **self.master_ng_dict)
mock_objects_nodegroup_list.return_value = [master_ng, worker_ng]
mock_driver.return_value = k8s_coreos_dr.Driver()
(template_path,
@ -738,6 +801,7 @@ class TestClusterConductorWithK8s(base.TestCase):
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.objects.NodeGroup.list')
@patch('magnum.drivers.common.driver.Driver.get_driver')
@patch('magnum.conductor.handlers.common.cert_manager'
'.sign_node_certificate')
@ -747,6 +811,7 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_generate_csr_and_key,
mock_sign_node_certificate,
mock_driver,
mock_objects_nodegroup_list,
mock_objects_cluster_template_get_by_uuid,
mock_get):
mock_driver.return_value = k8s_dr.Driver()
@ -756,10 +821,12 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get,
mock_objects_nodegroup_list,
missing_attr='dns_nameserver')
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.objects.NodeGroup.list')
@patch('magnum.drivers.common.driver.Driver.get_driver')
@patch('magnum.conductor.handlers.common.cert_manager'
'.sign_node_certificate')
@ -769,6 +836,7 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_generate_csr_and_key,
mock_sign_node_certificate,
mock_driver,
mock_objects_nodegroup_list,
mock_objects_cluster_template_get_by_uuid,
mock_get):
mock_driver.return_value = k8s_dr.Driver()
@ -778,10 +846,12 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get,
mock_objects_nodegroup_list,
missing_attr='image_id')
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.objects.NodeGroup.list')
@patch('magnum.drivers.common.driver.Driver.get_driver')
@patch('magnum.conductor.handlers.common.cert_manager'
'.sign_node_certificate')
@ -791,6 +861,7 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_generate_csr_and_key,
mock_sign_node_certificate,
mock_driver,
mock_objects_nodegroup_list,
mock_objects_cluster_template_get_by_uuid,
mock_get):
mock_driver.return_value = k8s_dr.Driver()
@ -800,10 +871,12 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get,
mock_objects_nodegroup_list,
missing_attr='docker_storage_driver')
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.objects.NodeGroup.list')
@patch('magnum.drivers.common.driver.Driver.get_driver')
@patch('magnum.conductor.handlers.common.cert_manager'
'.sign_node_certificate')
@ -813,6 +886,7 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_generate_csr_and_key,
mock_sign_node_certificate,
mock_driver,
mock_objects_nodegroup_list,
mock_objects_cluster_template_get_by_uuid,
mock_get):
mock_driver.return_value = k8s_dr.Driver()
@ -822,54 +896,12 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get,
mock_objects_nodegroup_list,
missing_attr='apiserver_port')
@patch('requests.get')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.drivers.common.driver.Driver.get_driver')
@patch('magnum.conductor.handlers.common.cert_manager'
'.sign_node_certificate')
@patch('magnum.common.x509.operations.generate_csr_and_key')
def test_extract_template_definition_without_node_count(
self,
mock_generate_csr_and_key,
mock_sign_node_certificate,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get):
mock_driver.return_value = k8s_dr.Driver()
self._test_extract_template_definition(
mock_generate_csr_and_key,
mock_sign_node_certificate,
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')
@patch('magnum.conductor.handlers.common.cert_manager'
'.sign_node_certificate')
@patch('magnum.common.x509.operations.generate_csr_and_key')
def test_extract_template_definition_without_master_count(
self,
mock_generate_csr_and_key,
mock_sign_node_certificate,
mock_driver,
mock_objects_cluster_template_get_by_uuid,
mock_get):
mock_driver.return_value = k8s_dr.Driver()
self._test_extract_template_definition(
mock_generate_csr_and_key,
mock_sign_node_certificate,
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.objects.NodeGroup.list')
@patch('magnum.drivers.common.driver.Driver.get_driver')
@patch('magnum.conductor.handlers.common.cert_manager'
'.sign_node_certificate')
@ -879,6 +911,7 @@ class TestClusterConductorWithK8s(base.TestCase):
mock_generate_csr_and_key,
mock_sign_node_certificate,
mock_driver,
mock_objects_nodegroup_list,
mock_objects_cluster_template_get_by_uuid,
reqget):
cluster_template = objects.ClusterTemplate(
@ -892,6 +925,9 @@ class TestClusterConductorWithK8s(base.TestCase):
cluster_dict = self.cluster_dict
cluster_dict['discovery_url'] = None
cluster = objects.Cluster(self.context, **cluster_dict)
worker_ng = objects.NodeGroup(self.context, **self.worker_ng_dict)
master_ng = objects.NodeGroup(self.context, **self.master_ng_dict)
mock_objects_nodegroup_list.return_value = [master_ng, worker_ng]
mock_driver.return_value = k8s_dr.Driver()
CONF.set_override('etcd_discovery_service_endpoint_format',
@ -1109,21 +1145,35 @@ class TestClusterConductorWithK8s(base.TestCase):
@patch('magnum.drivers.k8s_fedora_atomic_v1.driver.Driver.'
'_extract_template_definition')
@patch('magnum.common.clients.OpenStackClients')
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.objects.NodeGroup.list')
def test_update_stack(self,
mock_objects_nodegroup_list,
mock_objects_cluster_template_get_by_uuid,
mock_osc,
mock_extract_template_definition,
mock_get_template_contents):
mock_stack_id = 'xx-xx-xx-xx'
mock_heat_client = mock.MagicMock()
mock_stack = mock.MagicMock(parameters={'number_of_minions': 1})
mock_stacks = mock.MagicMock()
mock_stacks.get.return_value = mock_stack
mock_heat_client = mock.MagicMock(stacks=mock_stacks)
mock_osc.return_value.heat.return_value = mock_heat_client
mock_cluster = mock.MagicMock()
mock_cluster.stack_id = mock_stack_id
mock_template = objects.ClusterTemplate(
self.context, **self.cluster_template_dict)
mock_objects_cluster_template_get_by_uuid.return_value = mock_template
mock_cluster = objects.Cluster(self.context, **self.cluster_dict)
mock_cluster.cluster_template = mock_template
self.worker_ng_dict['node_count'] = 2
worker_ng = objects.NodeGroup(self.context, **self.worker_ng_dict)
master_ng = objects.NodeGroup(self.context, **self.master_ng_dict)
mock_objects_nodegroup_list.return_value = [master_ng, worker_ng]
k8s_dr.Driver().update_cluster({}, mock_cluster)
expected_args = {
'parameters': {'number_of_minions': mock_cluster.node_count},
'parameters': {'number_of_minions': '2'},
'existing': True,
'disable_rollback': True
}

92
magnum/tests/unit/conductor/handlers/test_mesos_cluster_conductor.py

@ -76,6 +76,38 @@ class TestClusterConductorWithMesos(base.TestCase):
'mesos_slave_work_dir': '/tmp/mesos/slave'
},
}
self.worker_ng_dict = {
'uuid': '5d12f6fd-a196-4bf0-ae4c-1f639a523a53',
'name': 'worker_ng',
'cluster_id': '5d12f6fd-a196-4bf0-ae4c-1f639a523a52',
'project_id': 'project_id',
'docker_volume_size': 20,
'labels': self.cluster_dict['labels'],
'flavor_id': 'flavor_id',
'image_id': 'image_id',
'node_addresses': ['172.17.2.4'],
'node_count': 1,
'role': 'worker',
'max_nodes': 5,
'min_nodes': 1,
'is_default': True
}
self.master_ng_dict = {
'uuid': '5d12f6fd-a196-4bf0-ae4c-1f639a523a54',
'name': 'master_ng',
'cluster_id': '5d12f6fd-a196-4bf0-ae4c-1f639a523a52',
'project_id': 'project_id',
'docker_volume_size': 20,
'labels': self.cluster_dict['labels'],
'flavor_id': 'master_flavor_id',
'image_id': 'image_id',
'node_addresses': ['172.17.2.18'],
'node_count': 1,
'role': 'master',
'max_nodes': 5,
'min_nodes': 1,
'is_default': True
}
self.context.user_name = 'mesos_user'
self.context.project_id = 'admin'
self.context.domain_name = 'domainname'
@ -91,16 +123,21 @@ class TestClusterConductorWithMesos(base.TestCase):
self.mock_osc.url_for.return_value = 'http://192.168.10.10:5000/v3'
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.objects.NodeGroup.list')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_all_values(
self,
mock_driver,
mock_objects_nodegroup_list,
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)
worker_ng = objects.NodeGroup(self.context, **self.worker_ng_dict)
master_ng = objects.NodeGroup(self.context, **self.master_ng_dict)
mock_objects_nodegroup_list.return_value = [master_ng, worker_ng]
mock_driver.return_value = mesos_dr.Driver()
(template_path,
@ -150,10 +187,12 @@ class TestClusterConductorWithMesos(base.TestCase):
env_files)
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.objects.NodeGroup.list')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def test_extract_template_definition_only_required(
self,
mock_driver,
mock_objects_nodegroup_list,
mock_objects_cluster_template_get_by_uuid):
not_required = ['image_id', 'master_flavor_id', 'flavor_id',
'dns_nameserver', 'fixed_network', 'http_proxy',
@ -167,6 +206,9 @@ class TestClusterConductorWithMesos(base.TestCase):
mock_objects_cluster_template_get_by_uuid.return_value = \
cluster_template
cluster = objects.Cluster(self.context, **self.cluster_dict)
worker_ng = objects.NodeGroup(self.context, **self.worker_ng_dict)
master_ng = objects.NodeGroup(self.context, **self.master_ng_dict)
mock_objects_nodegroup_list.return_value = [master_ng, worker_ng]
mock_driver.return_value = mesos_dr.Driver()
(template_path,
@ -208,12 +250,14 @@ class TestClusterConductorWithMesos(base.TestCase):
env_files)
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.objects.NodeGroup.list')
@patch('magnum.drivers.common.driver.Driver.get_driver')
@patch('magnum.common.keystone.KeystoneClientV3')
def test_extract_template_definition_with_lb_neutron(
self,
mock_kc,
mock_driver,
mock_objects_nodegroup_list,
mock_objects_cluster_template_get_by_uuid):
self.cluster_template_dict['master_lb_enabled'] = True
cluster_template = objects.ClusterTemplate(
@ -221,6 +265,9 @@ class TestClusterConductorWithMesos(base.TestCase):
mock_objects_cluster_template_get_by_uuid.return_value = \
cluster_template
cluster = objects.Cluster(self.context, **self.cluster_dict)
worker_ng = objects.NodeGroup(self.context, **self.worker_ng_dict)
master_ng = objects.NodeGroup(self.context, **self.master_ng_dict)
mock_objects_nodegroup_list.return_value = [master_ng, worker_ng]
mock_driver.return_value = mesos_dr.Driver()
mock_kc.return_value.client.services.list.return_value = []
@ -272,12 +319,14 @@ class TestClusterConductorWithMesos(base.TestCase):
env_files)
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.objects.NodeGroup.list')
@patch('magnum.drivers.common.driver.Driver.get_driver')
@patch('magnum.common.keystone.KeystoneClientV3')
def test_extract_template_definition_with_lb_octavia(
self,
mock_kc,
mock_driver,
mock_objects_nodegroup_list,
mock_objects_cluster_template_get_by_uuid):
self.cluster_template_dict['master_lb_enabled'] = True
cluster_template = objects.ClusterTemplate(
@ -285,6 +334,9 @@ class TestClusterConductorWithMesos(base.TestCase):
mock_objects_cluster_template_get_by_uuid.return_value = \
cluster_template
cluster = objects.Cluster(self.context, **self.cluster_dict)
worker_ng = objects.NodeGroup(self.context, **self.worker_ng_dict)
master_ng = objects.NodeGroup(self.context, **self.master_ng_dict)
mock_objects_nodegroup_list.return_value = [master_ng, worker_ng]
mock_driver.return_value = mesos_dr.Driver()
class Service(object):
@ -341,20 +393,25 @@ class TestClusterConductorWithMesos(base.TestCase):
env_files)
@patch('magnum.objects.ClusterTemplate.get_by_uuid')
@patch('magnum.objects.NodeGroup.list')
@patch('magnum.drivers.common.driver.Driver.get_driver')
@patch('magnum.common.keystone.KeystoneClientV3')
def test_extract_template_definition_multi_master(
self,
mock_kc,
mock_driver,
mock_objects_nodegroup_list,
mock_objects_cluster_template_get_by_uuid):
self.cluster_template_dict['master_lb_enabled'] = True
self.cluster_dict['master_count'] = 2
self.master_ng_dict['node_count'] = 2
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)
worker_ng = objects.NodeGroup(self.context, **self.worker_ng_dict)
master_ng = objects.NodeGroup(self.context, **self.master_ng_dict)
mock_objects_nodegroup_list.return_value = [master_ng, worker_ng]
mock_driver.return_value = mesos_dr.Driver()
mock_kc.return_value.client.services.list.return_value = []
@ -409,11 +466,23 @@ class TestClusterConductorWithMesos(base.TestCase):
@patch('magnum.conf.CONF')
@patch('magnum.common.clients.OpenStackClients')
@patch('magnum.drivers.common.driver.Driver.get_driver')
def setup_poll_test(self, mock_driver, mock_openstack_client, mock_conf,
mock_retrieve_cluster_template)