Allow labels on cluster create

Add labels as an option during cluster create. If not given,
the default is taken from the cluster template.

Add labels in the Cluster object and use that instead
of the one from ClusterTemplate.

Update both magnum and magnum cli documentation to reflect the above changes.

Partial-Bug: #1697651
Implements: blueprint flatten-attributes
Change-Id: I8990c78433dcbbca5bc4aa121678b02636346802
This commit is contained in:
Ricardo Rocha 2017-06-12 10:17:04 +00:00
parent 4fb91cc109
commit 3d04ed4cbb
19 changed files with 156 additions and 55 deletions

View File

@ -119,7 +119,7 @@ class DcosCentosTemplateDefinition(template_def.BaseTemplateDefinition):
'telemetry_enabled'] 'telemetry_enabled']
for label in label_list: for label in label_list:
extra_params[label] = cluster_template.labels.get(label) extra_params[label] = cluster.labels.get(label)
# By default, master_discovery is set to 'static' # By default, master_discovery is set to 'static'
# If --master-lb-enabled is specified, # If --master-lb-enabled is specified,

View File

@ -252,6 +252,7 @@ They are loosely grouped as: mandatory, infrastructure, COE specific.
way to pass additional parameters that are specific to a cluster driver. way to pass additional parameters that are specific to a cluster driver.
Refer to the subsection on labels for a list of the supported Refer to the subsection on labels for a list of the supported
key/value pairs and their usage. key/value pairs and their usage.
The value can be overridden at cluster creation.
--tls-disabled --tls-disabled
Transport Layer Security (TLS) is normally enabled to secure the Transport Layer Security (TLS) is normally enabled to secure the

View File

@ -92,6 +92,9 @@ class Bay(base.APIBase):
docker_volume_size = wtypes.IntegerType(minimum=1) docker_volume_size = wtypes.IntegerType(minimum=1)
"""The size in GB of the docker volume""" """The size in GB of the docker volume"""
labels = wtypes.DictType(str, str)
"""One or more key/value pairs"""
bay_create_timeout = wsme.wsattr(wtypes.IntegerType(minimum=0), default=60) bay_create_timeout = wsme.wsattr(wtypes.IntegerType(minimum=0), default=60)
"""Timeout for creating the bay in minutes. Default to 60 if not set""" """Timeout for creating the bay in minutes. Default to 60 if not set"""
@ -174,7 +177,7 @@ class Bay(base.APIBase):
def _convert_with_links(bay, url, expand=True): def _convert_with_links(bay, url, expand=True):
if not expand: if not expand:
bay.unset_fields_except(['uuid', 'name', 'baymodel_id', bay.unset_fields_except(['uuid', 'name', 'baymodel_id',
'docker_volume_size', 'docker_volume_size', 'labels',
'node_count', 'status', 'node_count', 'status',
'bay_create_timeout', 'master_count', 'bay_create_timeout', 'master_count',
'stack_id']) 'stack_id'])
@ -199,6 +202,7 @@ class Bay(base.APIBase):
node_count=2, node_count=2,
master_count=1, master_count=1,
docker_volume_size=1, docker_volume_size=1,
labels={},
bay_create_timeout=15, bay_create_timeout=15,
stack_id='49dc23f5-ffc9-40c3-9d34-7be7f9e34d63', stack_id='49dc23f5-ffc9-40c3-9d34-7be7f9e34d63',
status=fields.ClusterStatus.CREATE_COMPLETE, status=fields.ClusterStatus.CREATE_COMPLETE,
@ -424,6 +428,10 @@ class BaysController(base.Controller):
if bay.docker_volume_size == wtypes.Unset: if bay.docker_volume_size == wtypes.Unset:
bay.docker_volume_size = baymodel.docker_volume_size bay.docker_volume_size = baymodel.docker_volume_size
# If labels is not present, use baymodel value
if bay.labels is None:
bay.labels = baymodel.labels
bay_dict = bay.as_dict() bay_dict = bay.as_dict()
bay_dict['keypair'] = baymodel.keypair_id bay_dict['keypair'] = baymodel.keypair_id
attr_validator.validate_os_resources(context, baymodel.as_dict(), attr_validator.validate_os_resources(context, baymodel.as_dict(),

View File

@ -110,6 +110,9 @@ class Cluster(base.APIBase):
docker_volume_size = wtypes.IntegerType(minimum=1) docker_volume_size = wtypes.IntegerType(minimum=1)
"""The size in GB of the docker volume""" """The size in GB of the docker volume"""
labels = wtypes.DictType(str, str)
"""One or more key/value pairs"""
create_timeout = wsme.wsattr(wtypes.IntegerType(minimum=0), default=60) create_timeout = wsme.wsattr(wtypes.IntegerType(minimum=0), default=60)
"""Timeout for creating the cluster in minutes. Default to 60 if not set""" """Timeout for creating the cluster in minutes. Default to 60 if not set"""
@ -162,7 +165,7 @@ class Cluster(base.APIBase):
if not expand: if not expand:
cluster.unset_fields_except(['uuid', 'name', 'cluster_template_id', cluster.unset_fields_except(['uuid', 'name', 'cluster_template_id',
'keypair', 'docker_volume_size', 'keypair', 'docker_volume_size',
'node_count', 'status', 'labels', 'node_count', 'status',
'create_timeout', 'master_count', 'create_timeout', 'master_count',
'stack_id']) 'stack_id'])
@ -188,6 +191,7 @@ class Cluster(base.APIBase):
node_count=2, node_count=2,
master_count=1, master_count=1,
docker_volume_size=1, docker_volume_size=1,
labels={},
create_timeout=15, create_timeout=15,
stack_id='49dc23f5-ffc9-40c3-9d34-7be7f9e34d63', stack_id='49dc23f5-ffc9-40c3-9d34-7be7f9e34d63',
status=fields.ClusterStatus.CREATE_COMPLETE, status=fields.ClusterStatus.CREATE_COMPLETE,
@ -403,6 +407,10 @@ class ClustersController(base.Controller):
if cluster.docker_volume_size == wtypes.Unset: if cluster.docker_volume_size == wtypes.Unset:
cluster.docker_volume_size = cluster_template.docker_volume_size cluster.docker_volume_size = cluster_template.docker_volume_size
# If labels is not present, use cluster_template value
if cluster.labels == wtypes.Unset:
cluster.labels = cluster_template.labels
cluster_dict = cluster.as_dict() cluster_dict = cluster.as_dict()
attr_validator.validate_os_resources(context, attr_validator.validate_os_resources(context,

View File

@ -0,0 +1,30 @@
# 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.
"""add labels to cluster
Revision ID: a0e7c8450ab1
Revises: bc46ba6cf949
Create Date: 2017-06-12 10:08:05.501441
"""
# revision identifiers, used by Alembic.
revision = 'a0e7c8450ab1'
down_revision = 'aa0cc27839af'
from alembic import op
import sqlalchemy as sa
def upgrade():
op.add_column('cluster', sa.Column('labels',
sa.Text(), nullable=True))

View File

@ -116,6 +116,7 @@ class Cluster(Base):
cluster_template_id = Column(String(255)) cluster_template_id = Column(String(255))
keypair = Column(String(255)) keypair = Column(String(255))
docker_volume_size = Column(Integer()) docker_volume_size = Column(Integer())
labels = Column(JSONEncodedDict)
stack_id = Column(String(255)) stack_id = Column(String(255))
api_address = Column(String(255)) api_address = Column(String(255))
node_addresses = Column(JSONEncodedList) node_addresses = Column(JSONEncodedList)

View File

@ -75,7 +75,7 @@ class K8sFedoraTemplateDefinition(k8s_template_def.K8sTemplateDefinition):
# set docker_volume_type # set docker_volume_type
# use the configuration default if None provided # use the configuration default if None provided
docker_volume_type = cluster_template.labels.get( docker_volume_type = cluster.labels.get(
'docker_volume_type', CONF.cinder.default_docker_volume_type) 'docker_volume_type', CONF.cinder.default_docker_volume_type)
extra_params['docker_volume_type'] = docker_volume_type extra_params['docker_volume_type'] = docker_volume_type

View File

@ -116,7 +116,7 @@ class K8sTemplateDefinition(template_def.BaseTemplateDefinition):
'etcd_volume_size'] 'etcd_volume_size']
for label in label_list: for label in label_list:
extra_params[label] = cluster_template.labels.get(label) extra_params[label] = cluster.labels.get(label)
if cluster_template.registry_enabled: if cluster_template.registry_enabled:
extra_params['swift_region'] = CONF.docker_registry.swift_region extra_params['swift_region'] = CONF.docker_registry.swift_region

View File

@ -105,12 +105,12 @@ class SwarmFedoraTemplateDefinition(template_def.BaseTemplateDefinition):
# set docker_volume_type # set docker_volume_type
# use the configuration default if None provided # use the configuration default if None provided
docker_volume_type = cluster_template.labels.get( docker_volume_type = cluster.labels.get(
'docker_volume_type', CONF.cinder.default_docker_volume_type) 'docker_volume_type', CONF.cinder.default_docker_volume_type)
extra_params['docker_volume_type'] = docker_volume_type extra_params['docker_volume_type'] = docker_volume_type
for label in label_list: for label in label_list:
extra_params[label] = cluster_template.labels.get(label) extra_params[label] = cluster.labels.get(label)
if cluster_template.registry_enabled: if cluster_template.registry_enabled:
extra_params['swift_region'] = CONF.docker_registry.swift_region extra_params['swift_region'] = CONF.docker_registry.swift_region

View File

@ -68,7 +68,7 @@ class UbuntuMesosTemplateDefinition(template_def.BaseTemplateDefinition):
'mesos_slave_executor_env_variables'] 'mesos_slave_executor_env_variables']
for label in label_list: for label in label_list:
extra_params[label] = cluster_template.labels.get(label) extra_params[label] = cluster.labels.get(label)
scale_mgr = kwargs.pop('scale_manager', None) scale_mgr = kwargs.pop('scale_manager', None)
if scale_mgr: if scale_mgr:

View File

@ -43,8 +43,9 @@ class Cluster(base.MagnumPersistentObject, base.MagnumObject,
# Version 1.12: Added 'get_stats' method # Version 1.12: Added 'get_stats' method
# Version 1.13: Added get_count_all method # Version 1.13: Added get_count_all method
# Version 1.14: Added 'docker_volume_size' field # Version 1.14: Added 'docker_volume_size' field
# Version 1.15: Added 'labels' field
VERSION = '1.14' VERSION = '1.15'
dbapi = dbapi.get_instance() dbapi = dbapi.get_instance()
@ -57,6 +58,7 @@ class Cluster(base.MagnumPersistentObject, base.MagnumObject,
'cluster_template_id': fields.StringField(nullable=True), 'cluster_template_id': fields.StringField(nullable=True),
'keypair': fields.StringField(nullable=True), 'keypair': fields.StringField(nullable=True),
'docker_volume_size': fields.IntegerField(nullable=True), 'docker_volume_size': fields.IntegerField(nullable=True),
'labels': fields.DictOfStringsField(nullable=True),
'stack_id': fields.StringField(nullable=True), 'stack_id': fields.StringField(nullable=True),
'status': m_fields.ClusterStatusField(nullable=True), 'status': m_fields.ClusterStatusField(nullable=True),
'status_reason': fields.StringField(nullable=True), 'status_reason': fields.StringField(nullable=True),

View File

@ -790,6 +790,15 @@ class TestPost(api_base.FunctionalTest):
cluster, timeout = self.mock_cluster_create.call_args cluster, timeout = self.mock_cluster_create.call_args
self.assertEqual(3, cluster[0].docker_volume_size) self.assertEqual(3, cluster[0].docker_volume_size)
def test_create_cluster_with_labels(self):
bdict = apiutils.cluster_post_data()
bdict['labels'] = {'key': 'value'}
response = self.post_json('/clusters', bdict)
self.assertEqual('application/json', response.content_type)
self.assertEqual(202, response.status_int)
cluster, timeout = self.mock_cluster_create.call_args
self.assertEqual({'key': 'value'}, cluster[0].labels)
def test_create_cluster_without_docker_volume_size(self): def test_create_cluster_without_docker_volume_size(self):
bdict = apiutils.cluster_post_data() bdict = apiutils.cluster_post_data()
# Remove the default docker_volume_size from the cluster dict. # Remove the default docker_volume_size from the cluster dict.
@ -801,6 +810,16 @@ class TestPost(api_base.FunctionalTest):
# Verify docker_volume_size from ClusterTemplate is used # Verify docker_volume_size from ClusterTemplate is used
self.assertEqual(20, cluster[0].docker_volume_size) self.assertEqual(20, cluster[0].docker_volume_size)
def test_create_cluster_without_labels(self):
bdict = apiutils.cluster_post_data()
bdict.pop('labels')
response = self.post_json('/clusters', bdict)
self.assertEqual('application/json', response.content_type)
self.assertEqual(202, response.status_int)
cluster, timeout = self.mock_cluster_create.call_args
# Verify labels from ClusterTemplate is used
self.assertEqual({'key1': u'val1', 'key2': u'val2'}, cluster[0].labels)
def test_create_cluster_with_invalid_docker_volume_size(self): def test_create_cluster_with_invalid_docker_volume_size(self):
invalid_values = [(-1, None), ('notanint', None), invalid_values = [(-1, None), ('notanint', None),
(1, 'devicemapper'), (2, 'devicemapper')] (1, 'devicemapper'), (2, 'devicemapper')]
@ -812,6 +831,13 @@ class TestPost(api_base.FunctionalTest):
self.assertEqual(400, response.status_int) self.assertEqual(400, response.status_int)
self.assertTrue(response.json['errors']) self.assertTrue(response.json['errors'])
def test_create_cluster_with_invalid_labels(self):
bdict = apiutils.cluster_post_data(labels='invalid')
response = self.post_json('/clusters', bdict, expect_errors=True)
self.assertEqual('application/json', response.content_type)
self.assertEqual(400, response.status_int)
self.assertTrue(response.json['errors'])
class TestDelete(api_base.FunctionalTest): class TestDelete(api_base.FunctionalTest):
def setUp(self): def setUp(self):

View File

@ -56,7 +56,7 @@ class TestClusterConductorWithK8s(base.TestCase):
'grafana_admin_passwd': 'fake_pwd', 'grafana_admin_passwd': 'fake_pwd',
'kube_dashboard_enabled': 'True', 'kube_dashboard_enabled': 'True',
'docker_volume_type': 'lvmdriver-1', 'docker_volume_type': 'lvmdriver-1',
'etcd_volume_size': '0'}, 'etcd_volume_size': 0},
'tls_disabled': False, 'tls_disabled': False,
'server_type': 'vm', 'server_type': 'vm',
'registry_enabled': False, 'registry_enabled': False,
@ -84,6 +84,16 @@ class TestClusterConductorWithK8s(base.TestCase):
'trustee_user_id': '7b489f04-b458-4541-8179-6a48a553e656', 'trustee_user_id': '7b489f04-b458-4541-8179-6a48a553e656',
'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de', 'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de',
'coe_version': 'fake-version', 'coe_version': 'fake-version',
'labels': {'flannel_network_cidr': '10.101.0.0/16',
'flannel_network_subnetlen': '26',
'flannel_backend': 'vxlan',
'system_pods_initial_delay': '15',
'system_pods_timeout': '1',
'admission_control_list': 'fake_list',
'prometheus_monitoring': 'False',
'grafana_admin_passwd': 'fake_pwd',
'kube_dashboard_enabled': 'True',
'docker_volume_type': 'lvmdriver-1'},
} }
self.context.user_name = 'fake_user' self.context.user_name = 'fake_user'
self.context.tenant = 'fake_tenant' self.context.tenant = 'fake_tenant'
@ -160,7 +170,7 @@ class TestClusterConductorWithK8s(base.TestCase):
'grafana_admin_passwd': 'fake_pwd', 'grafana_admin_passwd': 'fake_pwd',
'kube_dashboard_enabled': 'True', 'kube_dashboard_enabled': 'True',
'docker_volume_type': 'lvmdriver-1', 'docker_volume_type': 'lvmdriver-1',
'etcd_volume_size': '0'}, 'etcd_volume_size': None},
'http_proxy': 'http_proxy', 'http_proxy': 'http_proxy',
'https_proxy': 'https_proxy', 'https_proxy': 'https_proxy',
'no_proxy': 'no_proxy', 'no_proxy': 'no_proxy',
@ -186,7 +196,7 @@ class TestClusterConductorWithK8s(base.TestCase):
'docker_volume_type': 'lvmdriver-1', 'docker_volume_type': 'lvmdriver-1',
'docker_storage_driver': 'devicemapper', 'docker_storage_driver': 'devicemapper',
'discovery_url': 'https://discovery.etcd.io/test', 'discovery_url': 'https://discovery.etcd.io/test',
'etcd_volume_size': '0', 'etcd_volume_size': None,
'flannel_network_cidr': '10.101.0.0/16', 'flannel_network_cidr': '10.101.0.0/16',
'flannel_network_subnetlen': '26', 'flannel_network_subnetlen': '26',
'flannel_backend': 'vxlan', 'flannel_backend': 'vxlan',
@ -270,7 +280,7 @@ class TestClusterConductorWithK8s(base.TestCase):
'docker_storage_driver': 'devicemapper', 'docker_storage_driver': 'devicemapper',
'docker_volume_size': 20, 'docker_volume_size': 20,
'docker_volume_type': 'lvmdriver-1', 'docker_volume_type': 'lvmdriver-1',
'etcd_volume_size': '0', 'etcd_volume_size': None,
'external_network': 'external_network_id', 'external_network': 'external_network_id',
'fixed_network': 'fixed_network', 'fixed_network': 'fixed_network',
'fixed_subnet': 'fixed_subnet', 'fixed_subnet': 'fixed_subnet',
@ -372,7 +382,7 @@ class TestClusterConductorWithK8s(base.TestCase):
'grafana_admin_passwd': 'fake_pwd', 'grafana_admin_passwd': 'fake_pwd',
'kube_dashboard_enabled': 'True', 'kube_dashboard_enabled': 'True',
'docker_volume_type': 'lvmdriver-1', 'docker_volume_type': 'lvmdriver-1',
'etcd_volume_size': '0', 'etcd_volume_size': None,
'insecure_registry_url': '10.0.0.1:5000', 'insecure_registry_url': '10.0.0.1:5000',
'kube_version': 'fake-version', 'kube_version': 'fake-version',
'magnum_url': 'http://127.0.0.1:9511/v1', 'magnum_url': 'http://127.0.0.1:9511/v1',
@ -440,7 +450,7 @@ class TestClusterConductorWithK8s(base.TestCase):
'network_driver': 'network_driver', 'network_driver': 'network_driver',
'volume_driver': 'volume_driver', 'volume_driver': 'volume_driver',
'discovery_url': 'https://discovery.etcd.io/test', 'discovery_url': 'https://discovery.etcd.io/test',
'etcd_volume_size': '0', 'etcd_volume_size': None,
'http_proxy': 'http_proxy', 'http_proxy': 'http_proxy',
'https_proxy': 'https_proxy', 'https_proxy': 'https_proxy',
'no_proxy': 'no_proxy', 'no_proxy': 'no_proxy',
@ -511,7 +521,7 @@ class TestClusterConductorWithK8s(base.TestCase):
'network_driver': 'network_driver', 'network_driver': 'network_driver',
'volume_driver': 'volume_driver', 'volume_driver': 'volume_driver',
'discovery_url': 'http://tokentest/h1/h2/h3', 'discovery_url': 'http://tokentest/h1/h2/h3',
'etcd_volume_size': '0', 'etcd_volume_size': None,
'http_proxy': 'http_proxy', 'http_proxy': 'http_proxy',
'https_proxy': 'https_proxy', 'https_proxy': 'https_proxy',
'no_proxy': 'no_proxy', 'no_proxy': 'no_proxy',
@ -709,7 +719,7 @@ class TestClusterConductorWithK8s(base.TestCase):
'docker_volume_type': 'lvmdriver-1', 'docker_volume_type': 'lvmdriver-1',
'docker_storage_driver': 'devicemapper', 'docker_storage_driver': 'devicemapper',
'discovery_url': 'https://address/token', 'discovery_url': 'https://address/token',
'etcd_volume_size': '0', 'etcd_volume_size': None,
'http_proxy': 'http_proxy', 'http_proxy': 'http_proxy',
'https_proxy': 'https_proxy', 'https_proxy': 'https_proxy',
'no_proxy': 'no_proxy', 'no_proxy': 'no_proxy',

View File

@ -66,6 +66,13 @@ class TestClusterConductorWithMesos(base.TestCase):
'trustee_password': 'fake_trustee_password', 'trustee_password': 'fake_trustee_password',
'trustee_user_id': '7b489f04-b458-4541-8179-6a48a553e656', 'trustee_user_id': '7b489f04-b458-4541-8179-6a48a553e656',
'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de', 'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de',
'labels': {'rexray_preempt': 'False',
'mesos_slave_isolation':
'docker/runtime,filesystem/linux',
'mesos_slave_image_providers': 'docker',
'mesos_slave_executor_env_variables': '{}',
'mesos_slave_work_dir': '/tmp/mesos/slave'
},
} }
self.context.user_name = 'mesos_user' self.context.user_name = 'mesos_user'
self.context.tenant = 'admin' self.context.tenant = 'admin'

View File

@ -74,6 +74,12 @@ class TestClusterConductorWithSwarm(base.TestCase):
'trustee_password': 'fake_trustee_password', 'trustee_password': 'fake_trustee_password',
'trustee_user_id': '7b489f04-b458-4541-8179-6a48a553e656', 'trustee_user_id': '7b489f04-b458-4541-8179-6a48a553e656',
'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de', 'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de',
'labels': {'docker_volume_type': 'lvmdriver-1',
'flannel_network_cidr': '10.101.0.0/16',
'flannel_network_subnetlen': '26',
'flannel_backend': 'vxlan',
'rexray_preempt': 'False',
'swarm_strategy': 'spread'},
'coe_version': 'fake-version' 'coe_version': 'fake-version'
} }

View File

@ -97,6 +97,7 @@ def get_test_cluster(**kw):
'created_at': kw.get('created_at'), 'created_at': kw.get('created_at'),
'updated_at': kw.get('updated_at'), 'updated_at': kw.get('updated_at'),
'docker_volume_size': kw.get('docker_volume_size'), 'docker_volume_size': kw.get('docker_volume_size'),
'labels': kw.get('labels'),
} }
# Only add Keystone trusts related attributes on demand since they may # Only add Keystone trusts related attributes on demand since they may

View File

@ -250,25 +250,25 @@ class AtomicK8sTemplateDefinitionTestCase(BaseTemplateDefinitionTestCase):
mock_context.user_name = 'fake_user' mock_context.user_name = 'fake_user'
mock_context.tenant = 'fake_tenant' mock_context.tenant = 'fake_tenant'
flannel_cidr = mock_cluster_template.labels.get('flannel_network_cidr') flannel_cidr = mock_cluster.labels.get('flannel_network_cidr')
flannel_subnet = mock_cluster_template.labels.get( flannel_subnet = mock_cluster.labels.get(
'flannel_network_subnetlen') 'flannel_network_subnetlen')
flannel_backend = mock_cluster_template.labels.get('flannel_backend') flannel_backend = mock_cluster.labels.get('flannel_backend')
system_pods_initial_delay = mock_cluster_template.labels.get( system_pods_initial_delay = mock_cluster.labels.get(
'system_pods_initial_delay') 'system_pods_initial_delay')
system_pods_timeout = mock_cluster_template.labels.get( system_pods_timeout = mock_cluster.labels.get(
'system_pods_timeout') 'system_pods_timeout')
admission_control_list = mock_cluster_template.labels.get( admission_control_list = mock_cluster.labels.get(
'admission_control_list') 'admission_control_list')
prometheus_monitoring = mock_cluster_template.labels.get( prometheus_monitoring = mock_cluster.labels.get(
'prometheus_monitoring') 'prometheus_monitoring')
grafana_admin_passwd = mock_cluster_template.labels.get( grafana_admin_passwd = mock_cluster.labels.get(
'grafana_admin_passwd') 'grafana_admin_passwd')
kube_dashboard_enabled = mock_cluster_template.labels.get( kube_dashboard_enabled = mock_cluster.labels.get(
'kube_dashboard_enabled') 'kube_dashboard_enabled')
docker_volume_type = mock_cluster_template.labels.get( docker_volume_type = mock_cluster.labels.get(
'docker_volume_type') 'docker_volume_type')
etcd_volume_size = mock_cluster_template.labels.get( etcd_volume_size = mock_cluster.labels.get(
'etcd_volume_size') 'etcd_volume_size')
k8s_def = k8sa_tdef.AtomicK8sTemplateDefinition() k8s_def = k8sa_tdef.AtomicK8sTemplateDefinition()
@ -330,25 +330,25 @@ class AtomicK8sTemplateDefinitionTestCase(BaseTemplateDefinitionTestCase):
mock_context.user_name = 'fake_user' mock_context.user_name = 'fake_user'
mock_context.tenant = 'fake_tenant' mock_context.tenant = 'fake_tenant'
flannel_cidr = mock_cluster_template.labels.get('flannel_network_cidr') flannel_cidr = mock_cluster.labels.get('flannel_network_cidr')
flannel_subnet = mock_cluster_template.labels.get( flannel_subnet = mock_cluster.labels.get(
'flannel_network_subnetlen') 'flannel_network_subnetlen')
flannel_backend = mock_cluster_template.labels.get('flannel_backend') flannel_backend = mock_cluster.labels.get('flannel_backend')
system_pods_initial_delay = mock_cluster_template.labels.get( system_pods_initial_delay = mock_cluster.labels.get(
'system_pods_initial_delay') 'system_pods_initial_delay')
system_pods_timeout = mock_cluster_template.labels.get( system_pods_timeout = mock_cluster.labels.get(
'system_pods_timeout') 'system_pods_timeout')
admission_control_list = mock_cluster_template.labels.get( admission_control_list = mock_cluster.labels.get(
'admission_control_list') 'admission_control_list')
prometheus_monitoring = mock_cluster_template.labels.get( prometheus_monitoring = mock_cluster.labels.get(
'prometheus_monitoring') 'prometheus_monitoring')
grafana_admin_passwd = mock_cluster_template.labels.get( grafana_admin_passwd = mock_cluster.labels.get(
'grafana_admin_passwd') 'grafana_admin_passwd')
kube_dashboard_enabled = mock_cluster_template.labels.get( kube_dashboard_enabled = mock_cluster.labels.get(
'kube_dashboard_enabled') 'kube_dashboard_enabled')
docker_volume_type = mock_cluster_template.labels.get( docker_volume_type = mock_cluster.labels.get(
'docker_volume_type') 'docker_volume_type')
etcd_volume_size = mock_cluster_template.labels.get( etcd_volume_size = mock_cluster.labels.get(
'etcd_volume_size') 'etcd_volume_size')
k8s_def = k8sa_tdef.AtomicK8sTemplateDefinition() k8s_def = k8sa_tdef.AtomicK8sTemplateDefinition()
@ -761,14 +761,14 @@ class AtomicSwarmTemplateDefinitionTestCase(base.TestCase):
mock_context.user_name = 'fake_user' mock_context.user_name = 'fake_user'
mock_context.tenant = 'fake_tenant' mock_context.tenant = 'fake_tenant'
docker_volume_type = mock_cluster_template.labels.get( docker_volume_type = mock_cluster.labels.get(
'docker_volume_type') 'docker_volume_type')
flannel_cidr = mock_cluster_template.labels.get('flannel_network_cidr') flannel_cidr = mock_cluster.labels.get('flannel_network_cidr')
flannel_subnet = mock_cluster_template.labels.get( flannel_subnet = mock_cluster.labels.get(
'flannel_network_subnetlen') 'flannel_network_subnetlen')
flannel_backend = mock_cluster_template.labels.get('flannel_backend') flannel_backend = mock_cluster.labels.get('flannel_backend')
rexray_preempt = mock_cluster_template.labels.get('rexray_preempt') rexray_preempt = mock_cluster.labels.get('rexray_preempt')
swarm_strategy = mock_cluster_template.labels.get('swarm_strategy') swarm_strategy = mock_cluster.labels.get('swarm_strategy')
swarm_def = swarm_tdef.AtomicSwarmTemplateDefinition() swarm_def = swarm_tdef.AtomicSwarmTemplateDefinition()
@ -923,18 +923,18 @@ class UbuntuMesosTemplateDefinitionTestCase(base.TestCase):
mock_context.domain_name = 'domainname' mock_context.domain_name = 'domainname'
mock_cluster_template = mock.MagicMock() mock_cluster_template = mock.MagicMock()
mock_cluster_template.tls_disabled = False mock_cluster_template.tls_disabled = False
rexray_preempt = mock_cluster_template.labels.get('rexray_preempt')
mesos_slave_isolation = mock_cluster_template.labels.get(
'mesos_slave_isolation')
mesos_slave_work_dir = mock_cluster_template.labels.get(
'mesos_slave_work_dir')
mesos_slave_image_providers = mock_cluster_template.labels.get(
'image_providers')
mesos_slave_executor_env_variables = mock_cluster_template.labels.get(
'mesos_slave_executor_env_variables')
mock_cluster = mock.MagicMock() mock_cluster = mock.MagicMock()
mock_cluster.uuid = '5d12f6fd-a196-4bf0-ae4c-1f639a523a52' mock_cluster.uuid = '5d12f6fd-a196-4bf0-ae4c-1f639a523a52'
del mock_cluster.stack_id del mock_cluster.stack_id
rexray_preempt = mock_cluster.labels.get('rexray_preempt')
mesos_slave_isolation = mock_cluster.labels.get(
'mesos_slave_isolation')
mesos_slave_work_dir = mock_cluster.labels.get(
'mesos_slave_work_dir')
mesos_slave_image_providers = mock_cluster.labels.get(
'image_providers')
mesos_slave_executor_env_variables = mock_cluster.labels.get(
'mesos_slave_executor_env_variables')
mock_osc = mock.MagicMock() mock_osc = mock.MagicMock()
mock_osc.cinder_region_name.return_value = 'RegionOne' mock_osc.cinder_region_name.return_value = 'RegionOne'
mock_osc_class.return_value = mock_osc mock_osc_class.return_value = mock_osc

View File

@ -39,6 +39,7 @@ class TestClusterObject(base.DbTestCase):
uuid=cluster_template_id) uuid=cluster_template_id)
self.fake_cluster['keypair'] = 'keypair1' self.fake_cluster['keypair'] = 'keypair1'
self.fake_cluster['docker_volume_size'] = 3 self.fake_cluster['docker_volume_size'] = 3
self.fake_cluster['labels'] = {}
@mock.patch('magnum.objects.ClusterTemplate.get_by_uuid') @mock.patch('magnum.objects.ClusterTemplate.get_by_uuid')
def test_get_by_id(self, mock_cluster_template_get): def test_get_by_id(self, mock_cluster_template_get):

View File

@ -355,7 +355,7 @@ class TestObject(test_base.TestCase, _TestObject):
# For more information on object version testing, read # For more information on object version testing, read
# http://docs.openstack.org/developer/magnum/objects.html # http://docs.openstack.org/developer/magnum/objects.html
object_data = { object_data = {
'Cluster': '1.14-281c582b16291c4f0666371e53975a5c', 'Cluster': '1.15-a8ed124644a6a53be1789f44578863f2',
'ClusterTemplate': '1.17-f1ce5212b46506360b41ab5cb7658af4', 'ClusterTemplate': '1.17-f1ce5212b46506360b41ab5cb7658af4',
'Certificate': '1.1-1924dc077daa844f0f9076332ef96815', 'Certificate': '1.1-1924dc077daa844f0f9076332ef96815',
'MyObj': '1.0-34c4b1aadefd177b13f9a2f894cc23cd', 'MyObj': '1.0-34c4b1aadefd177b13f9a2f894cc23cd',