From 530ca566f0554d69ac11dd3b919be25c2e689ed6 Mon Sep 17 00:00:00 2001 From: spisarski Date: Tue, 28 Nov 2017 13:16:54 -0700 Subject: Added cluster template creator/state machine class. Created class and tests for creating and managing cluster templates. JIRA: SNAPS-235 Change-Id: Ia91aef9507fc39d1814dce03169aab0b784721a6 Signed-off-by: spisarski --- docs/how-to-use/IntegrationTests.rst | 35 +++ snaps/config/cluster_template.py | 20 +- snaps/config/tests/cluster_template_tests.py | 12 +- snaps/domain/cluster_template.py | 42 +++ snaps/openstack/cluster_template.py | 94 +++++++ snaps/openstack/openstack_creator.py | 27 +- snaps/openstack/tests/cluster_template_tests.py | 301 ++++++++++++++++++++++ snaps/openstack/utils/magnum_utils.py | 30 +++ snaps/openstack/utils/tests/magnum_utils_tests.py | 14 + snaps/test_suite_builder.py | 5 + 10 files changed, 563 insertions(+), 17 deletions(-) create mode 100644 snaps/openstack/cluster_template.py create mode 100644 snaps/openstack/tests/cluster_template_tests.py diff --git a/docs/how-to-use/IntegrationTests.rst b/docs/how-to-use/IntegrationTests.rst index f3d17f7..80c93d0 100644 --- a/docs/how-to-use/IntegrationTests.rst +++ b/docs/how-to-use/IntegrationTests.rst @@ -669,3 +669,38 @@ ansible_utils_tests.py - AnsibleProvisioningTests | | Neutron 2 | apply a Ansible playbook containing Jinga2 substitution | | | | values | +---------------------------------------+---------------+-----------------------------------------------------------+ + +cluster_template_tests.py - CreateClusterTemplateTests +------------------------------------------------------ + ++----------------------------------------+---------------+-----------------------------------------------------------+ +| Test Name | Magnum API | Description | ++========================================+===============+===========================================================+ +| test_create_cluster_template | 1 | Tests the creation of a Cluster template with the class | +| | | OpenStackClusterTemplate | ++----------------------------------------+---------------+-----------------------------------------------------------+ +| test_create_delete_cluster_template | 1 | Tests the creation and deletiong of a Cluster template | +| | | with the class OpenStackClusterTemplate | ++----------------------------------------+---------------+-----------------------------------------------------------+ +| test_create_same_cluster_template | 1 | Tests the creation of a Cluster template 2x using the same| +| | | config object to ensure it was only created once | ++----------------------------------------+---------------+-----------------------------------------------------------+ +| test_create_cluster_template_bad_flavor| 1 | Tests to ensure OpenStackClusterTemplate#create() will | +| | | raise an exception when the flavor is invalid | ++----------------------------------------+---------------+-----------------------------------------------------------+ +| test_create_cluster_template_bad_master| 1 | Tests to ensure OpenStackClusterTemplate#create() will | +| _flavor | | raise an exception when the master flavor is invalid | ++----------------------------------------+---------------+-----------------------------------------------------------+ +| test_create_cluster_template_bad_image | 1 | Tests to ensure OpenStackClusterTemplate#create() will | +| | | raise an exception when the image is invalid | ++----------------------------------------+---------------+-----------------------------------------------------------+ +| test_create_cluster_template_bad | 1 | Tests to ensure OpenStackClusterTemplate#create() will | +| _keypair | | raise an exception when the keypair is invalid | ++----------------------------------------+---------------+-----------------------------------------------------------+ +| test_create_cluster_template_bad | 1 | Tests to ensure OpenStackClusterTemplate#create() will | +| _network_driver | | raise an exception when the network driver is invalid | ++----------------------------------------+---------------+-----------------------------------------------------------+ +| test_create_cluster_template_bad | 1 | Tests to ensure OpenStackClusterTemplate#create() will | +| _volume_driver | | raise an exception when the volume driver is invalid | ++----------------------------------------+---------------+-----------------------------------------------------------+ + diff --git a/snaps/config/cluster_template.py b/snaps/config/cluster_template.py index a20225a..a9ef45c 100644 --- a/snaps/config/cluster_template.py +++ b/snaps/config/cluster_template.py @@ -50,7 +50,7 @@ class ClusterTemplateConfig(object): def __init__(self, **kwargs): """ Constructor - :param name: the cluster type's name (required) + :param name: the cluster template's name (required) :param image: name or ID of the base image in Glance used to boot the cluster's servers. The image must have the attribute 'os-distro' defined as appropriate for the cluster @@ -110,7 +110,7 @@ class ClusterTemplateConfig(object): This is configured in the private Neutron network for the bay/cluster. (default provided by Magnum - 8.8.8.8) - :param public: denotes whether or not the cluster type is public + :param public: denotes whether or not the cluster template is public (default False) :param tls_disabled: denotes whether or not TLS should be enabled (default False) @@ -177,9 +177,9 @@ class ClusterTemplateConfig(object): if (not self.name or not self.image or not self.keypair or not self.external_net): - raise ClusterTypeConfigError( + raise ClusterTemplateConfigError( 'The attributes name, image, keypair, and ' - 'external_net are required for ClusterTypeConfig') + 'external_net are required for ClusterTemplateConfig') def magnum_dict(self): """ @@ -243,9 +243,9 @@ class ClusterTemplateConfig(object): return out -class ClusterTypeConfigError(Exception): +class ClusterTemplateConfigError(Exception): """ - Exception to be thrown when a cluster type configuration is incorrect + Exception to be thrown when a cluster template configuration is incorrect """ @@ -265,7 +265,8 @@ def map_server_type(server_type): for this_type in ServerType: if this_type.value == server_type: return this_type - raise ClusterTypeConfigError('Invalid server type - ' + server_type) + raise ClusterTemplateConfigError( + 'Invalid server type - ' + server_type) def map_coe(coe): @@ -284,7 +285,7 @@ def map_coe(coe): for this_type in ContainerOrchestrationEngine: if this_type.value == coe: return this_type - raise ClusterTypeConfigError('Invalid COE - ' + coe) + raise ClusterTemplateConfigError('Invalid COE - ' + coe) def map_docker_storage_driver(driver): @@ -303,4 +304,5 @@ def map_docker_storage_driver(driver): for this_type in DockerStorageDriver: if this_type.value == driver: return this_type - raise ClusterTypeConfigError('Invalid DockerStorageDriver - ' + driver) + raise ClusterTemplateConfigError( + 'Invalid DockerStorageDriver - ' + driver) diff --git a/snaps/config/tests/cluster_template_tests.py b/snaps/config/tests/cluster_template_tests.py index 5c695b9..e06b783 100644 --- a/snaps/config/tests/cluster_template_tests.py +++ b/snaps/config/tests/cluster_template_tests.py @@ -14,9 +14,9 @@ # limitations under the License. import unittest -from snaps.config.cluster_template import ClusterTemplateConfig, \ - ClusterTypeConfigError, ServerType, DockerStorageDriver, \ - ContainerOrchestrationEngine +from snaps.config.cluster_template import ( + ClusterTemplateConfig, ClusterTemplateConfigError, ServerType, + DockerStorageDriver, ContainerOrchestrationEngine) class ClusterTemplateConfigUnitTests(unittest.TestCase): @@ -25,15 +25,15 @@ class ClusterTemplateConfigUnitTests(unittest.TestCase): """ def test_no_params(self): - with self.assertRaises(ClusterTypeConfigError): + with self.assertRaises(ClusterTemplateConfigError): ClusterTemplateConfig() def test_empty_config(self): - with self.assertRaises(ClusterTypeConfigError): + with self.assertRaises(ClusterTemplateConfigError): ClusterTemplateConfig(config=dict()) def test_name_only(self): - with self.assertRaises(ClusterTypeConfigError): + with self.assertRaises(ClusterTemplateConfigError): ClusterTemplateConfig(name='foo') def test_minimal_named(self): diff --git a/snaps/domain/cluster_template.py b/snaps/domain/cluster_template.py index 01af88a..83892b2 100644 --- a/snaps/domain/cluster_template.py +++ b/snaps/domain/cluster_template.py @@ -131,3 +131,45 @@ class ClusterTemplate(object): self.volume_driver = kwargs.get('volume_driver') self.master_lb_enabled = kwargs.get('master_lb_enabled', True) self.labels = kwargs.get('labels') + + def __eq__(self, other): + labels_eq = False + if (self.labels and isinstance(self.labels, dict) + and len(self.labels) == 0): + if (other.labels and isinstance(other.labels, dict) + and len(other.labels) == 0): + labels_eq = True + elif not self.labels: + if (not other.labels or + (isinstance(other.labels, dict) + and len(other.labels) == 0)): + labels_eq = True + else: + labels_eq = self.labels == other.labels + + return (self.name == other.name + and self.id == other.id + and self.image == other.image + and self.keypair == other.keypair + and self.network_driver == other.network_driver + and self.external_net == other.external_net + and self.floating_ip_enabled == other.floating_ip_enabled + and self.docker_volume_size == other.docker_volume_size + and self.server_type == other.server_type + and self.flavor == other.flavor + and self.master_flavor == other.master_flavor + and self.coe == other.coe + and self.fixed_net == other.fixed_net + and self.fixed_subnet == other.fixed_subnet + and self.registry_enabled == other.registry_enabled + and self.insecure_registry == other.insecure_registry + and self.docker_storage_driver == other.docker_storage_driver + and self.dns_nameserver == other.dns_nameserver + and self.public == other.public + and self.tls_disabled == other.tls_disabled + and self.http_proxy == other.http_proxy + and self.https_proxy == other.https_proxy + and self.no_proxy == other.no_proxy + and self.volume_driver == other.volume_driver + and self.master_lb_enabled == other.master_lb_enabled + and labels_eq) diff --git a/snaps/openstack/cluster_template.py b/snaps/openstack/cluster_template.py new file mode 100644 index 0000000..c4ba76d --- /dev/null +++ b/snaps/openstack/cluster_template.py @@ -0,0 +1,94 @@ +# Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs") +# and others. 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 logging + +from magnumclient.common.apiclient.exceptions import NotFound + +from snaps.openstack.openstack_creator import OpenStackMagnumObject +from snaps.openstack.utils import magnum_utils + +__author__ = 'spisarski' + +logger = logging.getLogger('cluster_template') + + +class OpenStackClusterTemplate(OpenStackMagnumObject): + """ + Class responsible for managing an volume in OpenStack + """ + + def __init__(self, os_creds, cluster_template_config): + """ + Constructor + :param os_creds: The OpenStack connection credentials + :param cluster_template_config: The volume type settings + :return: + """ + super(self.__class__, self).__init__(os_creds) + + self.cluster_template_config = cluster_template_config + self.__cluster_template = None + + def initialize(self): + """ + Loads the existing Volume + :return: The Volume domain object or None + """ + super(self.__class__, self).initialize() + + self.__cluster_template = magnum_utils.get_cluster_template( + self._magnum, template_config=self.cluster_template_config) + + return self.__cluster_template + + def create(self): + """ + Creates the volume in OpenStack if it does not already exist and + returns the domain Volume object + :return: The Volume domain object or None + """ + self.initialize() + + if not self.__cluster_template: + self.__cluster_template = magnum_utils.create_cluster_template( + self._magnum, self.cluster_template_config) + logger.info( + 'Created volume type with name - %s', + self.cluster_template_config.name) + + return self.__cluster_template + + def clean(self): + """ + Cleanse environment of all artifacts + :return: void + """ + if self.__cluster_template: + try: + magnum_utils.delete_cluster_template( + self._magnum, self.__cluster_template.id) + except NotFound: + pass + + self.__cluster_template = None + + def get_cluster_template(self): + """ + Returns the domain Volume object as it was populated when create() was + called + :return: the object + """ + return self.__cluster_template diff --git a/snaps/openstack/openstack_creator.py b/snaps/openstack/openstack_creator.py index 945a78b..0caee9a 100644 --- a/snaps/openstack/openstack_creator.py +++ b/snaps/openstack/openstack_creator.py @@ -13,8 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. from snaps.domain.creator import CloudObject -from snaps.openstack.utils import (nova_utils, neutron_utils, keystone_utils, - cinder_utils) +from snaps.openstack.utils import ( + nova_utils, neutron_utils, keystone_utils, cinder_utils, magnum_utils) __author__ = 'spisarski' @@ -132,3 +132,26 @@ class OpenStackVolumeObject(OpenStackCloudObject): def clean(self): raise NotImplementedError('Do not override abstract method') + + +class OpenStackMagnumObject(OpenStackCloudObject): + """ + Abstract class for all OpenStack compute creators + """ + + def __init__(self, os_creds): + """ + Constructor + :param os_creds: the OpenStack credentials object + """ + super(OpenStackMagnumObject, self).__init__(os_creds) + self._magnum = None + + def initialize(self): + self._magnum = magnum_utils.magnum_client(self._os_creds) + + def create(self): + raise NotImplementedError('Do not override abstract method') + + def clean(self): + raise NotImplementedError('Do not override abstract method') diff --git a/snaps/openstack/tests/cluster_template_tests.py b/snaps/openstack/tests/cluster_template_tests.py new file mode 100644 index 0000000..791ace2 --- /dev/null +++ b/snaps/openstack/tests/cluster_template_tests.py @@ -0,0 +1,301 @@ +# Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs") +# and others. 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 magnumclient.common.apiclient.exceptions import BadRequest, NotFound + +from snaps.config.cluster_template import ClusterTemplateConfig +from snaps.config.flavor import FlavorConfig +from snaps.config.keypair import KeypairConfig +from snaps.openstack.cluster_template import OpenStackClusterTemplate +from snaps.openstack.create_flavor import OpenStackFlavor +from snaps.openstack.create_image import OpenStackImage +from snaps.openstack.create_keypairs import OpenStackKeypair +from snaps.openstack.tests import openstack_tests + +try: + from urllib.request import URLError +except ImportError: + from urllib2 import URLError + +import logging +import uuid + +from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase +from snaps.openstack.utils import magnum_utils + +__author__ = 'spisarski' + +logger = logging.getLogger('cluster_template_tests') + + +class CreateClusterTemplateTests(OSIntegrationTestCase): + """ + Test for the OpenStackClusterTemplate class defined in py + without any QoS Specs or Encryption + """ + + def setUp(self): + """ + Instantiates the CreateClusterTemplate object that is responsible for + downloading and creating an OS template config file within OpenStack + """ + super(self.__class__, self).__start__() + + self.guid = self.__class__.__name__ + '-' + str(uuid.uuid4()) + self.cluster_type_name = self.guid + '-cluster-type' + self.magnum = magnum_utils.magnum_client(self.os_creds) + + metadata = self.image_metadata + if not metadata: + metadata = dict() + if 'extra_properties' not in metadata: + metadata['extra_properties'] = dict() + metadata['extra_properties']['os_distro'] = 'cirros' + + os_image_settings = openstack_tests.cirros_image_settings( + name=self.guid + '-image', image_metadata=metadata) + + self.image_creator = OpenStackImage(self.os_creds, os_image_settings) + + self.flavor_creator = OpenStackFlavor( + self.os_creds, FlavorConfig( + name=self.guid + '-flavor', ram=512, disk=10, vcpus=1)) + + keypair_priv_filepath = 'tmp/' + self.guid + keypair_pub_filepath = keypair_priv_filepath + '.pub' + + self.keypair_creator = OpenStackKeypair( + self.os_creds, KeypairConfig( + name=self.guid + '-keypair', + public_filepath=keypair_pub_filepath, + private_filepath=keypair_priv_filepath)) + + self.cluster_template_creator = None + + self.cluster_template_config = ClusterTemplateConfig( + name=self.cluster_type_name, + image=self.image_creator.image_settings.name, + keypair=self.keypair_creator.keypair_settings.name, + external_net=self.ext_net_name, + flavor=self.flavor_creator.flavor_settings.name) + + try: + self.image_creator.create() + self.flavor_creator.create() + self.keypair_creator.create() + except: + self.tearDown() + raise + + def tearDown(self): + """ + Cleans the template config + """ + if self.cluster_template_creator: + try: + self.cluster_template_creator.clean() + except: + pass + if self.keypair_creator: + try: + self.keypair_creator.clean() + except: + pass + if self.flavor_creator: + try: + self.flavor_creator.clean() + except: + pass + if self.image_creator: + try: + self.image_creator.clean() + except: + pass + + super(self.__class__, self).__clean__() + + def test_create_cluster_template(self): + """ + Tests the creation of an OpenStack cluster template. + """ + # Create ClusterTemplate + self.cluster_template_creator = OpenStackClusterTemplate( + self.os_creds, self.cluster_template_config) + created_cluster_template = self.cluster_template_creator.create() + self.assertIsNotNone(created_cluster_template) + self.assertEqual(self.cluster_template_config.name, + created_cluster_template.name) + + retrieved_cluster_template1 = magnum_utils.get_cluster_template( + self.magnum, template_config=self.cluster_template_config) + self.assertIsNotNone(retrieved_cluster_template1) + self.assertEqual(created_cluster_template, retrieved_cluster_template1) + + retrieved_cluster_template2 = magnum_utils.get_cluster_template_by_id( + self.magnum, created_cluster_template.id) + self.assertEqual(created_cluster_template, retrieved_cluster_template2) + + def test_create_delete_cluster_template(self): + """ + Tests the creation then deletion of an OpenStack template config to + ensure clean() does not raise an Exception. + """ + # Create ClusterTemplate + self.cluster_template_creator = OpenStackClusterTemplate( + self.os_creds, self.cluster_template_config) + created_cluster_template = self.cluster_template_creator.create() + self.assertIsNotNone(created_cluster_template) + + self.cluster_template_creator.clean() + + tmplt = magnum_utils.get_cluster_template( + self.magnum, template_name=self.cluster_template_config.name) + self.assertIsNone(tmplt) + + def test_create_same_cluster_template(self): + """ + Tests the creation of an OpenStack cluster_template when one already + exists. + """ + # Create ClusterTemplate + self.cluster_template_creator = OpenStackClusterTemplate( + self.os_creds, self.cluster_template_config) + cluster_template1 = self.cluster_template_creator.create() + + retrieved_cluster_template = magnum_utils.get_cluster_template( + self.magnum, template_config=self.cluster_template_config) + self.assertEqual(cluster_template1, retrieved_cluster_template) + + # Should be retrieving the instance data + os_cluster_template_2 = OpenStackClusterTemplate( + self.os_creds, self.cluster_template_config) + cluster_template2 = os_cluster_template_2.create() + self.assertEqual(cluster_template2, cluster_template2) + + def test_create_cluster_template_bad_flavor(self): + """ + Tests the creation of an OpenStack cluster template raises an + exception with an invalid flavor. + """ + # Create ClusterTemplate + cluster_template_config = ClusterTemplateConfig( + name=self.cluster_type_name, + image=self.image_creator.image_settings.name, + keypair=self.keypair_creator.keypair_settings.name, + external_net=self.ext_net_name, + flavor='foo') + + self.cluster_template_creator = OpenStackClusterTemplate( + self.os_creds, cluster_template_config) + + with self.assertRaises(BadRequest): + self.cluster_template_creator.create() + + def test_create_cluster_template_bad_master_flavor(self): + """ + Tests the creation of an OpenStack cluster template raises an + exception with an invalid master flavor. + """ + # Create ClusterTemplate + cluster_template_config = ClusterTemplateConfig( + name=self.cluster_type_name, + image=self.image_creator.image_settings.name, + keypair=self.keypair_creator.keypair_settings.name, + external_net=self.ext_net_name, + flavor=self.flavor_creator.flavor_settings.name, + master_flavor='foo') + + self.cluster_template_creator = OpenStackClusterTemplate( + self.os_creds, cluster_template_config) + + with self.assertRaises(BadRequest): + self.cluster_template_creator.create() + + def test_create_cluster_template_bad_image(self): + """ + Tests the creation of an OpenStack cluster template raises an + exception with an invalid image. + """ + # Create ClusterTemplate + cluster_template_config = ClusterTemplateConfig( + name=self.cluster_type_name, + image='foo', + keypair=self.keypair_creator.keypair_settings.name, + external_net=self.ext_net_name, + flavor=self.flavor_creator.flavor_settings.name) + + self.cluster_template_creator = OpenStackClusterTemplate( + self.os_creds, cluster_template_config) + + with self.assertRaises(BadRequest): + self.cluster_template_creator.create() + + def test_create_cluster_template_bad_keypair(self): + """ + Tests the creation of an OpenStack cluster template raises an + exception with an invalid keypair. + """ + # Create ClusterTemplate + cluster_template_config = ClusterTemplateConfig( + name=self.cluster_type_name, + image=self.image_creator.image_settings.name, + keypair='foo', + external_net=self.ext_net_name, + flavor=self.flavor_creator.flavor_settings.name) + + self.cluster_template_creator = OpenStackClusterTemplate( + self.os_creds, cluster_template_config) + + with self.assertRaises(NotFound): + self.cluster_template_creator.create() + + def test_create_cluster_template_bad_network_driver(self): + """ + Tests the creation of an OpenStack cluster template raises an + exception with an invalid keypair. + """ + # Create ClusterTemplate + cluster_template_config = ClusterTemplateConfig( + name=self.cluster_type_name, + image=self.image_creator.image_settings.name, + keypair=self.keypair_creator.keypair_settings.name, + external_net=self.ext_net_name, + flavor=self.flavor_creator.flavor_settings.name, + network_driver='foo') + + self.cluster_template_creator = OpenStackClusterTemplate( + self.os_creds, cluster_template_config) + + with self.assertRaises(BadRequest): + self.cluster_template_creator.create() + + def test_create_cluster_template_bad_volume_driver(self): + """ + Tests the creation of an OpenStack cluster template raises an + exception with an invalid keypair. + """ + # Create ClusterTemplate + cluster_template_config = ClusterTemplateConfig( + name=self.cluster_type_name, + image=self.image_creator.image_settings.name, + keypair=self.keypair_creator.keypair_settings.name, + external_net=self.ext_net_name, + flavor=self.flavor_creator.flavor_settings.name, + volume_driver='foo') + + self.cluster_template_creator = OpenStackClusterTemplate( + self.os_creds, cluster_template_config) + + with self.assertRaises(BadRequest): + self.cluster_template_creator.create() diff --git a/snaps/openstack/utils/magnum_utils.py b/snaps/openstack/utils/magnum_utils.py index c744666..96ba6d1 100644 --- a/snaps/openstack/utils/magnum_utils.py +++ b/snaps/openstack/utils/magnum_utils.py @@ -35,6 +35,36 @@ def magnum_client(os_creds): session=keystone_utils.keystone_session(os_creds)) +def get_cluster_template(magnum, template_config=None, template_name=None): + """ + Returns the first ClusterTemplate domain object that matches the parameters + :param magnum: the Magnum client + :param template_config: a ClusterTemplateConfig object (optional) + :param template_name: the name of the template to lookup + :return: ClusterTemplate object or None + """ + name = None + if template_config: + name = template_config.name + elif template_name: + name = template_name + + os_templates = magnum.cluster_templates.list() + for os_template in os_templates: + if os_template.name == name: + return __map_os_cluster_template(os_template) + + +def get_cluster_template_by_id(magnum, tmplt_id): + """ + Returns the first ClusterTemplate domain object that matches the parameters + :param magnum: the Magnum client + :param tmplt_id: the template's ID + :return: ClusterTemplate object or None + """ + return __map_os_cluster_template(magnum.cluster_templates.get(tmplt_id)) + + def create_cluster_template(magnum, cluster_template_config): """ Creates a Magnum Cluster Template object in OpenStack diff --git a/snaps/openstack/utils/tests/magnum_utils_tests.py b/snaps/openstack/utils/tests/magnum_utils_tests.py index f6da810..766e3f2 100644 --- a/snaps/openstack/utils/tests/magnum_utils_tests.py +++ b/snaps/openstack/utils/tests/magnum_utils_tests.py @@ -144,6 +144,13 @@ class MagnumUtilsClusterTypeTests(OSComponentTestCase): self.assertTrue( validate_cluster_template(config, self.cluster_template)) + template_by_name = magnum_utils.get_cluster_template( + self.magnum, template_name=config.name) + self.assertEqual(self.cluster_template, template_by_name) + template_by_id = magnum_utils.get_cluster_template_by_id( + self.magnum, self.cluster_template.id) + self.assertEqual(self.cluster_template, template_by_id) + def test_create_cluster_template_all(self): config = ClusterTemplateConfig( name=self.cluster_type_name, @@ -168,6 +175,13 @@ class MagnumUtilsClusterTypeTests(OSComponentTestCase): self.assertTrue( validate_cluster_template(config, self.cluster_template)) + template_by_name = magnum_utils.get_cluster_template( + self.magnum, template_name=config.name) + self.assertEqual(self.cluster_template, template_by_name) + template_by_id = magnum_utils.get_cluster_template_by_id( + self.magnum, self.cluster_template.id) + self.assertEqual(self.cluster_template, template_by_id) + def test_create_cluster_template_bad_image(self): config = ClusterTemplateConfig( name=self.cluster_type_name, diff --git a/snaps/test_suite_builder.py b/snaps/test_suite_builder.py index 27d4f85..e73c400 100644 --- a/snaps/test_suite_builder.py +++ b/snaps/test_suite_builder.py @@ -55,6 +55,8 @@ from snaps.domain.test.vm_inst_tests import ( from snaps.domain.test.volume_tests import ( QoSSpecDomainObjectTests, VolumeTypeDomainObjectTests, VolumeTypeEncryptionObjectTests, VolumeDomainObjectTests) +from snaps.openstack.tests.cluster_template_tests import ( + CreateClusterTemplateTests) from snaps.openstack.tests.conf.os_credentials_tests import ( ProxySettingsUnitTests, OSCredsUnitTests) from snaps.openstack.tests.create_flavor_tests import ( @@ -729,3 +731,6 @@ def add_openstack_staging_tests(suite, os_creds, ext_net_name, suite.addTest(OSComponentTestCase.parameterize( MagnumUtilsClusterTypeTests, os_creds=os_creds, ext_net_name=ext_net_name, log_level=log_level)) + suite.addTest(OSComponentTestCase.parameterize( + CreateClusterTemplateTests, os_creds=os_creds, + ext_net_name=ext_net_name, log_level=log_level)) -- cgit 1.2.3-korg