Merge "Rename baymodel to cluster_template"

This commit is contained in:
Jenkins 2016-08-11 14:28:20 +00:00 committed by Gerrit Code Review
commit d8de9ba90e
8 changed files with 374 additions and 336 deletions

View File

@ -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.

View File

@ -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'])

View File

@ -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):

View File

@ -5837,43 +5837,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::
@ -5885,72 +5894,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',
@ -5958,23 +5974,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(
@ -5983,10 +6001,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

View File

@ -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')

View File

@ -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')

View File

@ -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'}]
)

View File

@ -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'}]
)