From 3f968d22b750d414fc6f8873e666433d909df294 Mon Sep 17 00:00:00 2001 From: Monty Taylor Date: Wed, 10 Aug 2016 09:50:13 -0500 Subject: [PATCH] Rename baymodel to cluster_template Magnum is renaming baymodel to cluster_template. Rather than releasing a shade version with baymodel and then later switching, go ahead and rename to cluster_template now. However, since the term isn't in wide use yet, provide aliases. Change-Id: Ieb1f067680f2312eacf75eed0d42edbd90c54beb --- ...num_baymodel_support-e35e5aab0b14ff75.yaml | 5 +- shade/_tasks.py | 8 +- shade/_utils.py | 10 +- shade/openstackcloud.py | 135 ++++++++------ shade/tests/functional/test_baymodels.py | 113 ------------ .../functional/test_cluster_templates.py | 115 ++++++++++++ shade/tests/unit/test_baymodels.py | 155 ---------------- shade/tests/unit/test_cluster_templates.py | 169 ++++++++++++++++++ 8 files changed, 374 insertions(+), 336 deletions(-) delete mode 100644 shade/tests/functional/test_baymodels.py create mode 100644 shade/tests/functional/test_cluster_templates.py delete mode 100644 shade/tests/unit/test_baymodels.py create mode 100644 shade/tests/unit/test_cluster_templates.py diff --git a/releasenotes/notes/add_magnum_baymodel_support-e35e5aab0b14ff75.yaml b/releasenotes/notes/add_magnum_baymodel_support-e35e5aab0b14ff75.yaml index 9c4f9b015..21dbed6f1 100644 --- a/releasenotes/notes/add_magnum_baymodel_support-e35e5aab0b14ff75.yaml +++ b/releasenotes/notes/add_magnum_baymodel_support-e35e5aab0b14ff75.yaml @@ -1,4 +1,7 @@ --- features: - Add support for Magnum baymodels, with the - usual methods (search/list/get/create/update/delete). + usual methods (search/list/get/create/update/delete). Due to upcoming + rename in Magnum from baymodel to cluster_template, the shade + functionality uses the term cluster_template. However, baymodel aliases + are provided for each api call. diff --git a/shade/_tasks.py b/shade/_tasks.py index 6947cb0e1..47ffd9538 100644 --- a/shade/_tasks.py +++ b/shade/_tasks.py @@ -939,22 +939,22 @@ class NeutronQuotasDelete(task_manager.Task): return client.neutron_client.delete_quota(**self.args) -class BaymodelList(task_manager.Task): +class ClusterTemplateList(task_manager.Task): def main(self, client): return client.magnum_client.baymodels.list(**self.args) -class BaymodelCreate(task_manager.Task): +class ClusterTemplateCreate(task_manager.Task): def main(self, client): return client.magnum_client.baymodels.create(**self.args) -class BaymodelDelete(task_manager.Task): +class ClusterTemplateDelete(task_manager.Task): def main(self, client): return client.magnum_client.baymodels.delete(self.args['id']) -class BaymodelUpdate(task_manager.Task): +class ClusterTemplateUpdate(task_manager.Task): def main(self, client): return client.magnum_client.baymodels.update( self.args['id'], self.args['patch']) diff --git a/shade/_utils.py b/shade/_utils.py index 0e1f622a9..ace3b1cd4 100644 --- a/shade/_utils.py +++ b/shade/_utils.py @@ -495,11 +495,11 @@ def normalize_flavors(flavors): return flavors -def normalize_baymodels(baymodels): - """Normalize Magnum baymodels.""" - for baymodel in baymodels: - baymodel['id'] = baymodel['uuid'] - return baymodels +def normalize_cluster_templates(cluster_templates): + """Normalize Magnum cluster_templates.""" + for cluster_template in cluster_templates: + cluster_template['id'] = cluster_template['uuid'] + return cluster_templates def valid_kwargs(*valid_args): diff --git a/shade/openstackcloud.py b/shade/openstackcloud.py index 5bbb2fcc2..a4702f884 100644 --- a/shade/openstackcloud.py +++ b/shade/openstackcloud.py @@ -5766,43 +5766,52 @@ class OpenStackCloud(object): return True @_utils.cache_on_arguments() - def list_baymodels(self, detail=False): - """List Magnum baymodels. + def list_cluster_templates(self, detail=False): + """List Magnum ClusterTemplates. + + ClusterTemplate is the new name for BayModel. :param bool detail. Flag to control if we need summarized or detailed output. - :returns: a list of dicts containing the baymodel details. + :returns: a list of dicts containing the cluster template details. :raises: ``OpenStackCloudException``: if something goes wrong during the openstack API call. """ - with _utils.shade_exceptions("Error fetching baymodel list"): - baymodels = self.manager.submitTask( - _tasks.BaymodelList(detail=detail)) - return _utils.normalize_baymodels(baymodels) + with _utils.shade_exceptions("Error fetching ClusterTemplate list"): + cluster_templates = self.manager.submitTask( + _tasks.ClusterTemplateList(detail=detail)) + return _utils.normalize_cluster_templates(cluster_templates) + list_baymodels = list_cluster_templates - def search_baymodels(self, name_or_id=None, filters=None, detail=False): - """Search Magnum baymodels. + def search_cluster_templates( + self, name_or_id=None, filters=None, detail=False): + """Search Magnum ClusterTemplates. - :param name_or_id: baymodel name or ID. + ClusterTemplate is the new name for BayModel. + + :param name_or_id: ClusterTemplate name or ID. :param filters: a dict containing additional filters to use. :param detail: a boolean to control if we need summarized or detailed output. - :returns: a list of dict containing the baymodels + :returns: a list of dict containing the ClusterTemplates :raises: ``OpenStackCloudException``: if something goes wrong during the openstack API call. """ - baymodels = self.list_baymodels(detail=detail) + cluster_templates = self.list_cluster_templates(detail=detail) return _utils._filter_list( - baymodels, name_or_id, filters) + cluster_templates, name_or_id, filters) + search_baymodels = search_cluster_templates - def get_baymodel(self, name_or_id, filters=None, detail=False): - """Get a baymodel by name or ID. + def get_cluster_template(self, name_or_id, filters=None, detail=False): + """Get a ClusterTemplate by name or ID. - :param name_or_id: Name or ID of the baymodel. + ClusterTemplate is the new name for BayModel. + + :param name_or_id: Name or ID of the ClusterTemplate. :param dict filters: A dictionary of meta data to use for further filtering. Elements of this dictionary may, themselves, be dictionaries. Example:: @@ -5814,72 +5823,79 @@ class OpenStackCloud(object): } } - :returns: A baymodel dict or None if no matching baymodel is - found. - + :returns: A ClusterTemplate dict or None if no matching + ClusterTemplate is found. """ - return _utils._get_entity(self.search_baymodels, name_or_id, + return _utils._get_entity(self.search_cluster_templates, name_or_id, filters=filters, detail=detail) + get_baymodel = get_cluster_template - def create_baymodel(self, name, image_id=None, keypair_id=None, - coe=None, **kwargs): - """Create a Magnum baymodel. + def create_cluster_template( + self, name, image_id=None, keypair_id=None, coe=None, **kwargs): + """Create a Magnum ClusterTemplate. - :param string name: Name of the baymodel. + ClusterTemplate is the new name for BayModel. + + :param string name: Name of the ClusterTemplate. :param string image_id: Name or ID of the image to use. :param string keypair_id: Name or ID of the keypair to use. - :param string coe: Name of the coe for the baymodel. + :param string coe: Name of the coe for the ClusterTemplate. Other arguments will be passed in kwargs. - :returns: a dict containing the baymodel description + :returns: a dict containing the ClusterTemplate description :raises: ``OpenStackCloudException`` if something goes wrong during the openstack API call """ with _utils.shade_exceptions( - "Error creating baymodel of name {baymodel_name}".format( - baymodel_name=name)): - baymodel = self.manager.submitTask( - _tasks.BaymodelCreate( + "Error creating ClusterTemplate of name" + " {cluster_template_name}".format( + cluster_template_name=name)): + cluster_template = self.manager.submitTask( + _tasks.ClusterTemplateCreate( name=name, image_id=image_id, keypair_id=keypair_id, coe=coe, **kwargs)) - self.list_baymodels.invalidate(self) - return baymodel + self.list_cluster_templates.invalidate(self) + return cluster_template + create_baymodel = create_cluster_template - def delete_baymodel(self, name_or_id): - """Delete a baymodel. + def delete_cluster_template(self, name_or_id): + """Delete a ClusterTemplate. - :param name_or_id: Name or unique ID of the baymodel. + ClusterTemplate is the new name for BayModel. + + :param name_or_id: Name or unique ID of the ClusterTemplate. :returns: True if the delete succeeded, False if the - baymodel was not found. + ClusterTemplate was not found. :raises: OpenStackCloudException on operation error. """ - self.list_baymodels.invalidate(self) - baymodel = self.get_baymodel(name_or_id) + self.list_cluster_templates.invalidate(self) + cluster_template = self.get_cluster_template(name_or_id) - if not baymodel: + if not cluster_template: self.log.debug( - "Baymodel {name_or_id} does not exist".format( + "ClusterTemplate {name_or_id} does not exist".format( name_or_id=name_or_id), exc_info=True) return False - with _utils.shade_exceptions("Error in deleting baymodel"): + with _utils.shade_exceptions("Error in deleting ClusterTemplate"): try: self.manager.submitTask( - _tasks.BaymodelDelete(id=baymodel['id'])) + _tasks.ClusterTemplateDelete(id=cluster_template['id'])) except magnum_exceptions.NotFound: self.log.debug( - "Baymodel {id} not found when deleting. Ignoring.".format( - id=baymodel['id'])) + "ClusterTemplate {id} not found when deleting." + " Ignoring.".format(id=cluster_template['id'])) return False - self.list_baymodels.invalidate(self) + self.list_cluster_templates.invalidate(self) return True + delete_baymodel = delete_cluster_template @_utils.valid_kwargs('name', 'image_id', 'flavor_id', 'master_flavor_id', 'keypair_id', 'external_network_id', 'fixed_network', @@ -5887,23 +5903,25 @@ class OpenStackCloud(object): 'coe', 'http_proxy', 'https_proxy', 'no_proxy', 'network_driver', 'tls_disabled', 'public', 'registry_enabled', 'volume_driver') - def update_baymodel(self, name_or_id, operation, **kwargs): - """Update a Magnum baymodel. + def update_cluster_template(self, name_or_id, operation, **kwargs): + """Update a Magnum ClusterTemplate. - :param name_or_id: Name or ID of the baymodel being updated. + ClusterTemplate is the new name for BayModel. + + :param name_or_id: Name or ID of the ClusterTemplate being updated. :param operation: Operation to perform - add, remove, replace. Other arguments will be passed with kwargs. - :returns: a dict representing the updated baymodel. + :returns: a dict representing the updated ClusterTemplate. :raises: OpenStackCloudException on operation error. """ - self.list_baymodels.invalidate(self) - baymodel = self.get_baymodel(name_or_id) - if not baymodel: + self.list_cluster_templates.invalidate(self) + cluster_template = self.get_cluster_template(name_or_id) + if not cluster_template: raise OpenStackCloudException( - "Baymodel %s not found." % name_or_id) + "ClusterTemplate %s not found." % name_or_id) if operation not in ['add', 'replace', 'remove']: raise TypeError( @@ -5912,10 +5930,11 @@ class OpenStackCloud(object): patches = _utils.generate_patches_from_kwargs(operation, **kwargs) with _utils.shade_exceptions( - "Error updating baymodel {0}".format(name_or_id)): + "Error updating ClusterTemplate {0}".format(name_or_id)): self.manager.submitTask( - _tasks.BaymodelUpdate( - id=baymodel['id'], patch=patches)) + _tasks.ClusterTemplateUpdate( + id=cluster_template['id'], patch=patches)) - new_baymodel = self.get_baymodel(name_or_id) - return new_baymodel + new_cluster_template = self.get_cluster_template(name_or_id) + return new_cluster_template + update_baymodel = update_cluster_template diff --git a/shade/tests/functional/test_baymodels.py b/shade/tests/functional/test_baymodels.py deleted file mode 100644 index c3d7e0283..000000000 --- a/shade/tests/functional/test_baymodels.py +++ /dev/null @@ -1,113 +0,0 @@ -# -*- coding: utf-8 -*- - -# 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. - -""" -test_baymodels ----------------------------------- - -Functional tests for `shade` baymodel methods. -""" - -from testtools import content - -from shade.tests.functional import base - -import os -import subprocess - - -class TestBaymodel(base.BaseFunctionalTestCase): - - def setUp(self): - super(TestBaymodel, self).setUp() - if not self.demo_cloud.has_service('container'): - self.skipTest('Container service not supported by cloud') - self.baymodel = None - - def test_baymodels(self): - '''Test baymodels functionality''' - name = 'fake-baymodel' - server_type = 'vm' - public = False - image_id = 'fedora-atomic-f23-dib' - tls_disabled = False - registry_enabled = False - coe = 'kubernetes' - keypair_id = 'testkey' - - self.addDetail('baymodel', content.text_content(name)) - self.addCleanup(self.cleanup, name) - - # generate a keypair to add to nova - ssh_directory = '/tmp/.ssh' - if not os.path.isdir(ssh_directory): - os.mkdir(ssh_directory) - subprocess.call( - ['ssh-keygen', '-t', 'rsa', '-N', '', '-f', - '%s/id_rsa_shade' % ssh_directory]) - - # add keypair to nova - with open('%s/id_rsa_shade.pub' % ssh_directory) as f: - key_content = f.read() - self.demo_cloud.create_keypair('testkey', key_content) - - # Test we can create a baymodel and we get it returned - self.baymodel = self.demo_cloud.create_baymodel( - name=name, image_id=image_id, - keypair_id=keypair_id, coe=coe) - self.assertEquals(self.baymodel['name'], name) - self.assertEquals(self.baymodel['image_id'], image_id) - self.assertEquals(self.baymodel['keypair_id'], keypair_id) - self.assertEquals(self.baymodel['coe'], coe) - self.assertEquals(self.baymodel['registry_enabled'], registry_enabled) - self.assertEquals(self.baymodel['tls_disabled'], tls_disabled) - self.assertEquals(self.baymodel['public'], public) - self.assertEquals(self.baymodel['server_type'], server_type) - - # Test that we can list baymodels - baymodels = self.demo_cloud.list_baymodels() - self.assertIsNotNone(baymodels) - - # Test we get the same baymodel with the get_baymodel method - baymodel_get = self.demo_cloud.get_baymodel(self.baymodel['uuid']) - self.assertEquals(baymodel_get['uuid'], self.baymodel['uuid']) - - # Test the get method also works by name - baymodel_get = self.demo_cloud.get_baymodel(name) - self.assertEquals(baymodel_get['name'], self.baymodel['name']) - - # Test we can update a field on the baymodel and only that field - # is updated - baymodel_update = self.demo_cloud.update_baymodel( - self.baymodel['uuid'], 'replace', tls_disabled=True) - self.assertEquals(baymodel_update['uuid'], - self.baymodel['uuid']) - self.assertEquals(baymodel_update['tls_disabled'], True) - - # Test we can delete and get True returned - baymodel_delete = self.demo_cloud.delete_baymodel( - self.baymodel['uuid']) - self.assertTrue(baymodel_delete) - - def cleanup(self, name): - if self.baymodel: - try: - self.demo_cloud.delete_baymodel(self.baymodel['name']) - except: - pass - - # delete keypair - self.demo_cloud.delete_keypair('testkey') - os.unlink('/tmp/.ssh/id_rsa_shade') - os.unlink('/tmp/.ssh/id_rsa_shade.pub') diff --git a/shade/tests/functional/test_cluster_templates.py b/shade/tests/functional/test_cluster_templates.py new file mode 100644 index 000000000..92dd7a641 --- /dev/null +++ b/shade/tests/functional/test_cluster_templates.py @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- + +# 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. + +""" +test_cluster_templates +---------------------------------- + +Funself.ctional tests for `shade` cluster_template methods. +""" + +from testtools import content + +from shade.tests.functional import base + +import os +import subprocess + + +class TestClusterTemplate(base.BaseFunctionalTestCase): + + def setUp(self): + super(TestClusterTemplate, self).setUp() + if not self.demo_cloud.has_service('container'): + self.skipTest('Container service not supported by cloud') + self.ct = None + + def test_cluster_templates(self): + '''Test cluster_templates functionality''' + name = 'fake-cluster_template' + server_type = 'vm' + public = False + image_id = 'fedora-atomic-f23-dib' + tls_disabled = False + registry_enabled = False + coe = 'kubernetes' + keypair_id = 'testkey' + + self.addDetail('cluster_template', content.text_content(name)) + self.addCleanup(self.cleanup, name) + + # generate a keypair to add to nova + ssh_directory = '/tmp/.ssh' + if not os.path.isdir(ssh_directory): + os.mkdir(ssh_directory) + subprocess.call( + ['ssh-keygen', '-t', 'rsa', '-N', '', '-f', + '%s/id_rsa_shade' % ssh_directory]) + + # add keypair to nova + with open('%s/id_rsa_shade.pub' % ssh_directory) as f: + key_content = f.read() + self.demo_cloud.create_keypair('testkey', key_content) + + # Test we can create a cluster_template and we get it returned + self.ct = self.demo_cloud.create_cluster_template( + name=name, image_id=image_id, + keypair_id=keypair_id, coe=coe) + self.assertEquals(self.ct['name'], name) + self.assertEquals(self.ct['image_id'], image_id) + self.assertEquals(self.ct['keypair_id'], keypair_id) + self.assertEquals(self.ct['coe'], coe) + self.assertEquals(self.ct['registry_enabled'], registry_enabled) + self.assertEquals(self.ct['tls_disabled'], tls_disabled) + self.assertEquals(self.ct['public'], public) + self.assertEquals(self.ct['server_type'], server_type) + + # Test that we can list cluster_templates + cluster_templates = self.demo_cloud.list_cluster_templates() + self.assertIsNotNone(cluster_templates) + + # Test we get the same cluster_template with the + # get_cluster_template method + cluster_template_get = self.demo_cloud.get_cluster_template( + self.ct['uuid']) + self.assertEquals(cluster_template_get['uuid'], self.ct['uuid']) + + # Test the get method also works by name + cluster_template_get = self.demo_cloud.get_cluster_template(name) + self.assertEquals(cluster_template_get['name'], self.ct['name']) + + # Test we can update a field on the cluster_template and only that + # field is updated + cluster_template_update = self.demo_cloud.update_cluster_template( + self.ct['uuid'], 'replace', tls_disabled=True) + self.assertEquals(cluster_template_update['uuid'], + self.ct['uuid']) + self.assertEquals(cluster_template_update['tls_disabled'], True) + + # Test we can delete and get True returned + cluster_template_delete = self.demo_cloud.delete_cluster_template( + self.ct['uuid']) + self.assertTrue(cluster_template_delete) + + def cleanup(self, name): + if self.ct: + try: + self.demo_cloud.delete_cluster_template(self.ct['name']) + except: + pass + + # delete keypair + self.demo_cloud.delete_keypair('testkey') + os.unlink('/tmp/.ssh/id_rsa_shade') + os.unlink('/tmp/.ssh/id_rsa_shade.pub') diff --git a/shade/tests/unit/test_baymodels.py b/shade/tests/unit/test_baymodels.py deleted file mode 100644 index 04d9c8fc8..000000000 --- a/shade/tests/unit/test_baymodels.py +++ /dev/null @@ -1,155 +0,0 @@ -# -*- coding: utf-8 -*- - -# 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 mock -import munch - -import shade -import testtools -from shade.tests.unit import base - - -baymodel_obj = munch.Munch( - apiserver_port=None, - uuid='fake-uuid', - human_id=None, - name='fake-baymodel', - server_type='vm', - public=False, - image_id='fake-image', - tls_disabled=False, - registry_enabled=False, - coe='fake-coe', - keypair_id='fake-key', -) - -baymodel_detail_obj = munch.Munch( - links={}, - labels={}, - apiserver_port=None, - uuid='fake-uuid', - human_id=None, - name='fake-baymodel', - server_type='vm', - public=False, - image_id='fake-image', - tls_disabled=False, - registry_enabled=False, - coe='fake-coe', - created_at='fake-date', - updated_at=None, - master_flavor_id=None, - no_proxy=None, - https_proxy=None, - keypair_id='fake-key', - docker_volume_size=1, - external_network_id='public', - cluster_distro='fake-distro', - volume_driver=None, - network_driver='fake-driver', - fixed_network=None, - flavor_id='fake-flavor', - dns_nameserver='8.8.8.8', -) - - -class TestBaymodels(base.TestCase): - - def setUp(self): - super(TestBaymodels, self).setUp() - self.cloud = shade.openstack_cloud(validate=False) - - @mock.patch.object(shade.OpenStackCloud, 'magnum_client') - def test_list_baymodels_without_detail(self, mock_magnum): - mock_magnum.baymodels.list.return_value = [baymodel_obj, ] - baymodels_list = self.cloud.list_baymodels() - mock_magnum.baymodels.list.assert_called_with(detail=False) - self.assertEqual(baymodels_list[0], baymodel_obj) - - @mock.patch.object(shade.OpenStackCloud, 'magnum_client') - def test_list_baymodels_with_detail(self, mock_magnum): - mock_magnum.baymodels.list.return_value = [baymodel_detail_obj, ] - baymodels_list = self.cloud.list_baymodels(detail=True) - mock_magnum.baymodels.list.assert_called_with(detail=True) - self.assertEqual(baymodels_list[0], baymodel_detail_obj) - - @mock.patch.object(shade.OpenStackCloud, 'magnum_client') - def test_search_baymodels_by_name(self, mock_magnum): - mock_magnum.baymodels.list.return_value = [baymodel_obj, ] - - baymodels = self.cloud.search_baymodels(name_or_id='fake-baymodel') - mock_magnum.baymodels.list.assert_called_with(detail=False) - - self.assertEquals(1, len(baymodels)) - self.assertEquals('fake-uuid', baymodels[0]['uuid']) - - @mock.patch.object(shade.OpenStackCloud, 'magnum_client') - def test_search_baymodels_not_found(self, mock_magnum): - mock_magnum.baymodels.list.return_value = [baymodel_obj, ] - - baymodels = self.cloud.search_baymodels(name_or_id='non-existent') - - mock_magnum.baymodels.list.assert_called_with(detail=False) - self.assertEquals(0, len(baymodels)) - - @mock.patch.object(shade.OpenStackCloud, 'search_baymodels') - def test_get_baymodel(self, mock_search): - mock_search.return_value = [baymodel_obj, ] - r = self.cloud.get_baymodel('fake-baymodel') - self.assertIsNotNone(r) - self.assertDictEqual(baymodel_obj, r) - - @mock.patch.object(shade.OpenStackCloud, 'search_baymodels') - def test_get_baymodel_not_found(self, mock_search): - mock_search.return_value = [] - r = self.cloud.get_baymodel('doesNotExist') - self.assertIsNone(r) - - @mock.patch.object(shade.OpenStackCloud, 'magnum_client') - def test_create_baymodel(self, mock_magnum): - self.cloud.create_baymodel( - name=baymodel_obj.name, image_id=baymodel_obj.image_id, - keypair_id=baymodel_obj.keypair_id, coe=baymodel_obj.coe) - mock_magnum.baymodels.create.assert_called_once_with( - name=baymodel_obj.name, image_id=baymodel_obj.image_id, - keypair_id=baymodel_obj.keypair_id, coe=baymodel_obj.coe - ) - - @mock.patch.object(shade.OpenStackCloud, 'magnum_client') - def test_create_baymodel_exception(self, mock_magnum): - mock_magnum.baymodels.create.side_effect = Exception() - with testtools.ExpectedException( - shade.OpenStackCloudException, - "Error creating baymodel of name fake-baymodel" - ): - self.cloud.create_baymodel('fake-baymodel') - - @mock.patch.object(shade.OpenStackCloud, 'magnum_client') - def test_delete_baymodel(self, mock_magnum): - mock_magnum.baymodels.list.return_value = [baymodel_obj] - self.cloud.delete_baymodel('fake-uuid') - mock_magnum.baymodels.delete.assert_called_once_with( - 'fake-uuid' - ) - - @mock.patch.object(shade.OpenStackCloud, 'magnum_client') - def test_update_baymodel(self, mock_magnum): - new_name = 'new-baymodel' - mock_magnum.baymodels.list.return_value = [baymodel_obj] - self.cloud.update_baymodel('fake-uuid', 'replace', name=new_name) - mock_magnum.baymodels.update.assert_called_once_with( - 'fake-uuid', [{'path': '/name', 'op': 'replace', - 'value': 'new-baymodel'}] - ) diff --git a/shade/tests/unit/test_cluster_templates.py b/shade/tests/unit/test_cluster_templates.py new file mode 100644 index 000000000..8c480e86a --- /dev/null +++ b/shade/tests/unit/test_cluster_templates.py @@ -0,0 +1,169 @@ +# -*- coding: utf-8 -*- + +# 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 mock +import munch + +import shade +import testtools +from shade.tests.unit import base + + +cluster_template_obj = munch.Munch( + apiserver_port=None, + uuid='fake-uuid', + human_id=None, + name='fake-cluster-template', + server_type='vm', + public=False, + image_id='fake-image', + tls_disabled=False, + registry_enabled=False, + coe='fake-coe', + keypair_id='fake-key', +) + +cluster_template_detail_obj = munch.Munch( + links={}, + labels={}, + apiserver_port=None, + uuid='fake-uuid', + human_id=None, + name='fake-cluster-template', + server_type='vm', + public=False, + image_id='fake-image', + tls_disabled=False, + registry_enabled=False, + coe='fake-coe', + created_at='fake-date', + updated_at=None, + master_flavor_id=None, + no_proxy=None, + https_proxy=None, + keypair_id='fake-key', + docker_volume_size=1, + external_network_id='public', + cluster_distro='fake-distro', + volume_driver=None, + network_driver='fake-driver', + fixed_network=None, + flavor_id='fake-flavor', + dns_nameserver='8.8.8.8', +) + + +class TestClusterTemplates(base.TestCase): + + def setUp(self): + super(TestClusterTemplates, self).setUp() + self.cloud = shade.openstack_cloud(validate=False) + + @mock.patch.object(shade.OpenStackCloud, 'magnum_client') + def test_list_cluster_templates_without_detail(self, mock_magnum): + mock_magnum.baymodels.list.return_value = [ + cluster_template_obj] + cluster_templates_list = self.cloud.list_cluster_templates() + mock_magnum.baymodels.list.assert_called_with(detail=False) + self.assertEqual(cluster_templates_list[0], cluster_template_obj) + + @mock.patch.object(shade.OpenStackCloud, 'magnum_client') + def test_list_cluster_templates_with_detail(self, mock_magnum): + mock_magnum.baymodels.list.return_value = [ + cluster_template_detail_obj] + cluster_templates_list = self.cloud.list_cluster_templates(detail=True) + mock_magnum.baymodels.list.assert_called_with(detail=True) + self.assertEqual( + cluster_templates_list[0], cluster_template_detail_obj) + + @mock.patch.object(shade.OpenStackCloud, 'magnum_client') + def test_search_cluster_templates_by_name(self, mock_magnum): + mock_magnum.baymodels.list.return_value = [ + cluster_template_obj] + + cluster_templates = self.cloud.search_cluster_templates( + name_or_id='fake-cluster-template') + mock_magnum.baymodels.list.assert_called_with(detail=False) + + self.assertEquals(1, len(cluster_templates)) + self.assertEquals('fake-uuid', cluster_templates[0]['uuid']) + + @mock.patch.object(shade.OpenStackCloud, 'magnum_client') + def test_search_cluster_templates_not_found(self, mock_magnum): + mock_magnum.baymodels.list.return_value = [ + cluster_template_obj] + + cluster_templates = self.cloud.search_cluster_templates( + name_or_id='non-existent') + + mock_magnum.baymodels.list.assert_called_with(detail=False) + self.assertEquals(0, len(cluster_templates)) + + @mock.patch.object(shade.OpenStackCloud, 'search_cluster_templates') + def test_get_cluster_template(self, mock_search): + mock_search.return_value = [cluster_template_obj, ] + r = self.cloud.get_cluster_template('fake-cluster-template') + self.assertIsNotNone(r) + self.assertDictEqual(cluster_template_obj, r) + + @mock.patch.object(shade.OpenStackCloud, 'search_cluster_templates') + def test_get_cluster_template_not_found(self, mock_search): + mock_search.return_value = [] + r = self.cloud.get_cluster_template('doesNotExist') + self.assertIsNone(r) + + @mock.patch.object(shade.OpenStackCloud, 'magnum_client') + def test_create_cluster_template(self, mock_magnum): + self.cloud.create_cluster_template( + name=cluster_template_obj.name, + image_id=cluster_template_obj.image_id, + keypair_id=cluster_template_obj.keypair_id, + coe=cluster_template_obj.coe) + mock_magnum.baymodels.create.assert_called_once_with( + name=cluster_template_obj.name, + image_id=cluster_template_obj.image_id, + keypair_id=cluster_template_obj.keypair_id, + coe=cluster_template_obj.coe + ) + + @mock.patch.object(shade.OpenStackCloud, 'magnum_client') + def test_create_cluster_template_exception(self, mock_magnum): + mock_magnum.baymodels.create.side_effect = Exception() + with testtools.ExpectedException( + shade.OpenStackCloudException, + "Error creating ClusterTemplate of name fake-cluster-template" + ): + self.cloud.create_cluster_template('fake-cluster-template') + + @mock.patch.object(shade.OpenStackCloud, 'magnum_client') + def test_delete_cluster_template(self, mock_magnum): + mock_magnum.baymodels.list.return_value = [ + cluster_template_obj] + self.cloud.delete_cluster_template('fake-uuid') + mock_magnum.baymodels.delete.assert_called_once_with( + 'fake-uuid' + ) + + @mock.patch.object(shade.OpenStackCloud, 'magnum_client') + def test_update_cluster_template(self, mock_magnum): + new_name = 'new-cluster-template' + mock_magnum.baymodels.list.return_value = [ + cluster_template_obj] + self.cloud.update_cluster_template( + 'fake-uuid', 'replace', name=new_name) + mock_magnum.baymodels.update.assert_called_once_with( + 'fake-uuid', [{'path': '/name', 'op': 'replace', + 'value': 'new-cluster-template'}] + )