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
This commit is contained in:
parent
e5ac401ce7
commit
3f968d22b7
@ -1,4 +1,7 @@
|
|||||||
---
|
---
|
||||||
features:
|
features:
|
||||||
- Add support for Magnum baymodels, with the
|
- 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.
|
||||||
|
@ -939,22 +939,22 @@ class NeutronQuotasDelete(task_manager.Task):
|
|||||||
return client.neutron_client.delete_quota(**self.args)
|
return client.neutron_client.delete_quota(**self.args)
|
||||||
|
|
||||||
|
|
||||||
class BaymodelList(task_manager.Task):
|
class ClusterTemplateList(task_manager.Task):
|
||||||
def main(self, client):
|
def main(self, client):
|
||||||
return client.magnum_client.baymodels.list(**self.args)
|
return client.magnum_client.baymodels.list(**self.args)
|
||||||
|
|
||||||
|
|
||||||
class BaymodelCreate(task_manager.Task):
|
class ClusterTemplateCreate(task_manager.Task):
|
||||||
def main(self, client):
|
def main(self, client):
|
||||||
return client.magnum_client.baymodels.create(**self.args)
|
return client.magnum_client.baymodels.create(**self.args)
|
||||||
|
|
||||||
|
|
||||||
class BaymodelDelete(task_manager.Task):
|
class ClusterTemplateDelete(task_manager.Task):
|
||||||
def main(self, client):
|
def main(self, client):
|
||||||
return client.magnum_client.baymodels.delete(self.args['id'])
|
return client.magnum_client.baymodels.delete(self.args['id'])
|
||||||
|
|
||||||
|
|
||||||
class BaymodelUpdate(task_manager.Task):
|
class ClusterTemplateUpdate(task_manager.Task):
|
||||||
def main(self, client):
|
def main(self, client):
|
||||||
return client.magnum_client.baymodels.update(
|
return client.magnum_client.baymodels.update(
|
||||||
self.args['id'], self.args['patch'])
|
self.args['id'], self.args['patch'])
|
||||||
|
@ -495,11 +495,11 @@ def normalize_flavors(flavors):
|
|||||||
return flavors
|
return flavors
|
||||||
|
|
||||||
|
|
||||||
def normalize_baymodels(baymodels):
|
def normalize_cluster_templates(cluster_templates):
|
||||||
"""Normalize Magnum baymodels."""
|
"""Normalize Magnum cluster_templates."""
|
||||||
for baymodel in baymodels:
|
for cluster_template in cluster_templates:
|
||||||
baymodel['id'] = baymodel['uuid']
|
cluster_template['id'] = cluster_template['uuid']
|
||||||
return baymodels
|
return cluster_templates
|
||||||
|
|
||||||
|
|
||||||
def valid_kwargs(*valid_args):
|
def valid_kwargs(*valid_args):
|
||||||
|
@ -5766,43 +5766,52 @@ class OpenStackCloud(object):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
@_utils.cache_on_arguments()
|
@_utils.cache_on_arguments()
|
||||||
def list_baymodels(self, detail=False):
|
def list_cluster_templates(self, detail=False):
|
||||||
"""List Magnum baymodels.
|
"""List Magnum ClusterTemplates.
|
||||||
|
|
||||||
|
ClusterTemplate is the new name for BayModel.
|
||||||
|
|
||||||
:param bool detail. Flag to control if we need summarized or
|
:param bool detail. Flag to control if we need summarized or
|
||||||
detailed output.
|
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
|
:raises: ``OpenStackCloudException``: if something goes wrong during
|
||||||
the openstack API call.
|
the openstack API call.
|
||||||
"""
|
"""
|
||||||
with _utils.shade_exceptions("Error fetching baymodel list"):
|
with _utils.shade_exceptions("Error fetching ClusterTemplate list"):
|
||||||
baymodels = self.manager.submitTask(
|
cluster_templates = self.manager.submitTask(
|
||||||
_tasks.BaymodelList(detail=detail))
|
_tasks.ClusterTemplateList(detail=detail))
|
||||||
return _utils.normalize_baymodels(baymodels)
|
return _utils.normalize_cluster_templates(cluster_templates)
|
||||||
|
list_baymodels = list_cluster_templates
|
||||||
|
|
||||||
def search_baymodels(self, name_or_id=None, filters=None, detail=False):
|
def search_cluster_templates(
|
||||||
"""Search Magnum baymodels.
|
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 filters: a dict containing additional filters to use.
|
||||||
:param detail: a boolean to control if we need summarized or
|
:param detail: a boolean to control if we need summarized or
|
||||||
detailed output.
|
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
|
:raises: ``OpenStackCloudException``: if something goes wrong during
|
||||||
the openstack API call.
|
the openstack API call.
|
||||||
"""
|
"""
|
||||||
baymodels = self.list_baymodels(detail=detail)
|
cluster_templates = self.list_cluster_templates(detail=detail)
|
||||||
return _utils._filter_list(
|
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):
|
def get_cluster_template(self, name_or_id, filters=None, detail=False):
|
||||||
"""Get a baymodel by name or ID.
|
"""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:
|
:param dict filters:
|
||||||
A dictionary of meta data to use for further filtering. Elements
|
A dictionary of meta data to use for further filtering. Elements
|
||||||
of this dictionary may, themselves, be dictionaries. Example::
|
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
|
:returns: A ClusterTemplate dict or None if no matching
|
||||||
found.
|
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)
|
filters=filters, detail=detail)
|
||||||
|
get_baymodel = get_cluster_template
|
||||||
|
|
||||||
def create_baymodel(self, name, image_id=None, keypair_id=None,
|
def create_cluster_template(
|
||||||
coe=None, **kwargs):
|
self, name, image_id=None, keypair_id=None, coe=None, **kwargs):
|
||||||
"""Create a Magnum baymodel.
|
"""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 image_id: Name or ID of the image to use.
|
||||||
:param string keypair_id: Name or ID of the keypair 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.
|
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
|
:raises: ``OpenStackCloudException`` if something goes wrong during
|
||||||
the openstack API call
|
the openstack API call
|
||||||
"""
|
"""
|
||||||
with _utils.shade_exceptions(
|
with _utils.shade_exceptions(
|
||||||
"Error creating baymodel of name {baymodel_name}".format(
|
"Error creating ClusterTemplate of name"
|
||||||
baymodel_name=name)):
|
" {cluster_template_name}".format(
|
||||||
baymodel = self.manager.submitTask(
|
cluster_template_name=name)):
|
||||||
_tasks.BaymodelCreate(
|
cluster_template = self.manager.submitTask(
|
||||||
|
_tasks.ClusterTemplateCreate(
|
||||||
name=name, image_id=image_id,
|
name=name, image_id=image_id,
|
||||||
keypair_id=keypair_id, coe=coe, **kwargs))
|
keypair_id=keypair_id, coe=coe, **kwargs))
|
||||||
|
|
||||||
self.list_baymodels.invalidate(self)
|
self.list_cluster_templates.invalidate(self)
|
||||||
return baymodel
|
return cluster_template
|
||||||
|
create_baymodel = create_cluster_template
|
||||||
|
|
||||||
def delete_baymodel(self, name_or_id):
|
def delete_cluster_template(self, name_or_id):
|
||||||
"""Delete a baymodel.
|
"""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
|
:returns: True if the delete succeeded, False if the
|
||||||
baymodel was not found.
|
ClusterTemplate was not found.
|
||||||
|
|
||||||
:raises: OpenStackCloudException on operation error.
|
:raises: OpenStackCloudException on operation error.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.list_baymodels.invalidate(self)
|
self.list_cluster_templates.invalidate(self)
|
||||||
baymodel = self.get_baymodel(name_or_id)
|
cluster_template = self.get_cluster_template(name_or_id)
|
||||||
|
|
||||||
if not baymodel:
|
if not cluster_template:
|
||||||
self.log.debug(
|
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),
|
name_or_id=name_or_id),
|
||||||
exc_info=True)
|
exc_info=True)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
with _utils.shade_exceptions("Error in deleting baymodel"):
|
with _utils.shade_exceptions("Error in deleting ClusterTemplate"):
|
||||||
try:
|
try:
|
||||||
self.manager.submitTask(
|
self.manager.submitTask(
|
||||||
_tasks.BaymodelDelete(id=baymodel['id']))
|
_tasks.ClusterTemplateDelete(id=cluster_template['id']))
|
||||||
except magnum_exceptions.NotFound:
|
except magnum_exceptions.NotFound:
|
||||||
self.log.debug(
|
self.log.debug(
|
||||||
"Baymodel {id} not found when deleting. Ignoring.".format(
|
"ClusterTemplate {id} not found when deleting."
|
||||||
id=baymodel['id']))
|
" Ignoring.".format(id=cluster_template['id']))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.list_baymodels.invalidate(self)
|
self.list_cluster_templates.invalidate(self)
|
||||||
return True
|
return True
|
||||||
|
delete_baymodel = delete_cluster_template
|
||||||
|
|
||||||
@_utils.valid_kwargs('name', 'image_id', 'flavor_id', 'master_flavor_id',
|
@_utils.valid_kwargs('name', 'image_id', 'flavor_id', 'master_flavor_id',
|
||||||
'keypair_id', 'external_network_id', 'fixed_network',
|
'keypair_id', 'external_network_id', 'fixed_network',
|
||||||
@ -5887,23 +5903,25 @@ class OpenStackCloud(object):
|
|||||||
'coe', 'http_proxy', 'https_proxy', 'no_proxy',
|
'coe', 'http_proxy', 'https_proxy', 'no_proxy',
|
||||||
'network_driver', 'tls_disabled', 'public',
|
'network_driver', 'tls_disabled', 'public',
|
||||||
'registry_enabled', 'volume_driver')
|
'registry_enabled', 'volume_driver')
|
||||||
def update_baymodel(self, name_or_id, operation, **kwargs):
|
def update_cluster_template(self, name_or_id, operation, **kwargs):
|
||||||
"""Update a Magnum baymodel.
|
"""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.
|
:param operation: Operation to perform - add, remove, replace.
|
||||||
|
|
||||||
Other arguments will be passed with kwargs.
|
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.
|
:raises: OpenStackCloudException on operation error.
|
||||||
"""
|
"""
|
||||||
self.list_baymodels.invalidate(self)
|
self.list_cluster_templates.invalidate(self)
|
||||||
baymodel = self.get_baymodel(name_or_id)
|
cluster_template = self.get_cluster_template(name_or_id)
|
||||||
if not baymodel:
|
if not cluster_template:
|
||||||
raise OpenStackCloudException(
|
raise OpenStackCloudException(
|
||||||
"Baymodel %s not found." % name_or_id)
|
"ClusterTemplate %s not found." % name_or_id)
|
||||||
|
|
||||||
if operation not in ['add', 'replace', 'remove']:
|
if operation not in ['add', 'replace', 'remove']:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
@ -5912,10 +5930,11 @@ class OpenStackCloud(object):
|
|||||||
patches = _utils.generate_patches_from_kwargs(operation, **kwargs)
|
patches = _utils.generate_patches_from_kwargs(operation, **kwargs)
|
||||||
|
|
||||||
with _utils.shade_exceptions(
|
with _utils.shade_exceptions(
|
||||||
"Error updating baymodel {0}".format(name_or_id)):
|
"Error updating ClusterTemplate {0}".format(name_or_id)):
|
||||||
self.manager.submitTask(
|
self.manager.submitTask(
|
||||||
_tasks.BaymodelUpdate(
|
_tasks.ClusterTemplateUpdate(
|
||||||
id=baymodel['id'], patch=patches))
|
id=cluster_template['id'], patch=patches))
|
||||||
|
|
||||||
new_baymodel = self.get_baymodel(name_or_id)
|
new_cluster_template = self.get_cluster_template(name_or_id)
|
||||||
return new_baymodel
|
return new_cluster_template
|
||||||
|
update_baymodel = update_cluster_template
|
||||||
|
@ -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')
|
|
115
shade/tests/functional/test_cluster_templates.py
Normal file
115
shade/tests/functional/test_cluster_templates.py
Normal 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')
|
@ -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'}]
|
|
||||||
)
|
|
169
shade/tests/unit/test_cluster_templates.py
Normal file
169
shade/tests/unit/test_cluster_templates.py
Normal 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'}]
|
||||||
|
)
|
Loading…
x
Reference in New Issue
Block a user