Add magnum baymodel calls to shade.
Change-Id: Icba6929d32ae2cc47ccb776e24bc8beac6b717d2
This commit is contained in:
parent
1c25357f18
commit
8732fa7ec3
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- Add support for Magnum baymodels, with the
|
||||||
|
usual methods (search/list/get/create/update/delete).
|
@ -907,3 +907,24 @@ class CinderQuotasGet(task_manager.Task):
|
|||||||
class CinderQuotasDelete(task_manager.Task):
|
class CinderQuotasDelete(task_manager.Task):
|
||||||
def main(self, client):
|
def main(self, client):
|
||||||
return client.cinder_client.quotas.delete(**self.args)
|
return client.cinder_client.quotas.delete(**self.args)
|
||||||
|
|
||||||
|
|
||||||
|
class BaymodelList(task_manager.Task):
|
||||||
|
def main(self, client):
|
||||||
|
return client.magnum_client.baymodels.list(**self.args)
|
||||||
|
|
||||||
|
|
||||||
|
class BaymodelCreate(task_manager.Task):
|
||||||
|
def main(self, client):
|
||||||
|
return client.magnum_client.baymodels.create(**self.args)
|
||||||
|
|
||||||
|
|
||||||
|
class BaymodelDelete(task_manager.Task):
|
||||||
|
def main(self, client):
|
||||||
|
return client.magnum_client.baymodels.delete(self.args['id'])
|
||||||
|
|
||||||
|
|
||||||
|
class BaymodelUpdate(task_manager.Task):
|
||||||
|
def main(self, client):
|
||||||
|
return client.magnum_client.baymodels.update(
|
||||||
|
self.args['id'], self.args['patch'])
|
||||||
|
@ -495,6 +495,13 @@ def normalize_flavors(flavors):
|
|||||||
return flavors
|
return flavors
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_baymodels(baymodels):
|
||||||
|
"""Normalize Magnum baymodels."""
|
||||||
|
for baymodel in baymodels:
|
||||||
|
baymodel['id'] = baymodel['uuid']
|
||||||
|
return baymodels
|
||||||
|
|
||||||
|
|
||||||
def valid_kwargs(*valid_args):
|
def valid_kwargs(*valid_args):
|
||||||
# This decorator checks if argument passed as **kwargs to a function are
|
# This decorator checks if argument passed as **kwargs to a function are
|
||||||
# present in valid_args.
|
# present in valid_args.
|
||||||
@ -759,3 +766,21 @@ def range_filter(data, key, range_exp):
|
|||||||
if int(d[key]) == val_range[1]:
|
if int(d[key]) == val_range[1]:
|
||||||
filtered.append(d)
|
filtered.append(d)
|
||||||
return filtered
|
return filtered
|
||||||
|
|
||||||
|
|
||||||
|
def generate_patches_from_kwargs(operation, **kwargs):
|
||||||
|
"""Given a set of parameters, returns a list with the
|
||||||
|
valid patch values.
|
||||||
|
|
||||||
|
:param string operation: The operation to perform.
|
||||||
|
:param list kwargs: Dict of parameters.
|
||||||
|
|
||||||
|
:returns: A list with the right patch values.
|
||||||
|
"""
|
||||||
|
patches = []
|
||||||
|
for k, v in kwargs.items():
|
||||||
|
patch = {'op': operation,
|
||||||
|
'value': v,
|
||||||
|
'path': '/%s' % k}
|
||||||
|
patches.append(patch)
|
||||||
|
return patches
|
||||||
|
@ -30,6 +30,7 @@ import cinderclient.exceptions as cinder_exceptions
|
|||||||
import glanceclient
|
import glanceclient
|
||||||
import glanceclient.exc
|
import glanceclient.exc
|
||||||
import heatclient.client
|
import heatclient.client
|
||||||
|
import magnumclient.exceptions as magnum_exceptions
|
||||||
from heatclient.common import event_utils
|
from heatclient.common import event_utils
|
||||||
from heatclient.common import template_utils
|
from heatclient.common import template_utils
|
||||||
from heatclient import exc as heat_exceptions
|
from heatclient import exc as heat_exceptions
|
||||||
@ -5652,3 +5653,158 @@ class OpenStackCloud(object):
|
|||||||
_tasks.RecordSetDelete(zone=zone['id'], recordset=name_or_id))
|
_tasks.RecordSetDelete(zone=zone['id'], recordset=name_or_id))
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@_utils.cache_on_arguments()
|
||||||
|
def list_baymodels(self, detail=False):
|
||||||
|
"""List Magnum baymodels.
|
||||||
|
|
||||||
|
:param bool detail. Flag to control if we need summarized or
|
||||||
|
detailed output.
|
||||||
|
|
||||||
|
:returns: a list of dicts containing the baymodel 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)
|
||||||
|
|
||||||
|
def search_baymodels(self, name_or_id=None, filters=None, detail=False):
|
||||||
|
"""Search Magnum baymodels.
|
||||||
|
|
||||||
|
:param name_or_id: baymodel 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
|
||||||
|
|
||||||
|
:raises: ``OpenStackCloudException``: if something goes wrong during
|
||||||
|
the openstack API call.
|
||||||
|
"""
|
||||||
|
baymodels = self.list_baymodels(detail=detail)
|
||||||
|
return _utils._filter_list(
|
||||||
|
baymodels, name_or_id, filters)
|
||||||
|
|
||||||
|
def get_baymodel(self, name_or_id, filters=None, detail=False):
|
||||||
|
"""Get a baymodel by name or ID.
|
||||||
|
|
||||||
|
:param name_or_id: Name or ID of the baymodel.
|
||||||
|
:param dict filters:
|
||||||
|
A dictionary of meta data to use for further filtering. Elements
|
||||||
|
of this dictionary may, themselves, be dictionaries. Example::
|
||||||
|
|
||||||
|
{
|
||||||
|
'last_name': 'Smith',
|
||||||
|
'other': {
|
||||||
|
'gender': 'Female'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:returns: A baymodel dict or None if no matching baymodel is
|
||||||
|
found.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return _utils._get_entity(self.search_baymodels, name_or_id,
|
||||||
|
filters=filters, detail=detail)
|
||||||
|
|
||||||
|
def create_baymodel(self, name, image_id=None, keypair_id=None,
|
||||||
|
coe=None, **kwargs):
|
||||||
|
"""Create a Magnum baymodel.
|
||||||
|
|
||||||
|
:param string name: Name of the baymodel.
|
||||||
|
: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.
|
||||||
|
|
||||||
|
Other arguments will be passed in kwargs.
|
||||||
|
|
||||||
|
:returns: a dict containing the baymodel 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(
|
||||||
|
name=name, image_id=image_id,
|
||||||
|
keypair_id=keypair_id, coe=coe, **kwargs))
|
||||||
|
|
||||||
|
self.list_baymodels.invalidate(self)
|
||||||
|
return baymodel
|
||||||
|
|
||||||
|
def delete_baymodel(self, name_or_id):
|
||||||
|
"""Delete a baymodel.
|
||||||
|
|
||||||
|
:param name_or_id: Name or unique ID of the baymodel.
|
||||||
|
:returns: True if the delete succeeded, False if the
|
||||||
|
baymodel was not found.
|
||||||
|
|
||||||
|
:raises: OpenStackCloudException on operation error.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.list_baymodels.invalidate(self)
|
||||||
|
baymodel = self.get_baymodel(name_or_id)
|
||||||
|
|
||||||
|
if not baymodel:
|
||||||
|
self.log.debug(
|
||||||
|
"Baymodel {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"):
|
||||||
|
try:
|
||||||
|
self.manager.submitTask(
|
||||||
|
_tasks.BaymodelDelete(id=baymodel['id']))
|
||||||
|
except magnum_exceptions.NotFound:
|
||||||
|
self.log.debug(
|
||||||
|
"Baymodel {id} not found when deleting. Ignoring.".format(
|
||||||
|
id=baymodel['id']))
|
||||||
|
return False
|
||||||
|
|
||||||
|
self.list_baymodels.invalidate(self)
|
||||||
|
return True
|
||||||
|
|
||||||
|
@_utils.valid_kwargs('name', 'image_id', 'flavor_id', 'master_flavor_id',
|
||||||
|
'keypair_id', 'external_network_id', 'fixed_network',
|
||||||
|
'dns_nameserver', 'docker_volume_size', 'labels',
|
||||||
|
'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.
|
||||||
|
|
||||||
|
:param name_or_id: Name or ID of the baymodel being updated.
|
||||||
|
:param operation: Operation to perform - add, remove, replace.
|
||||||
|
|
||||||
|
Other arguments will be passed with kwargs.
|
||||||
|
|
||||||
|
:returns: a dict representing the updated baymodel.
|
||||||
|
|
||||||
|
:raises: OpenStackCloudException on operation error.
|
||||||
|
"""
|
||||||
|
self.list_baymodels.invalidate(self)
|
||||||
|
baymodel = self.get_baymodel(name_or_id)
|
||||||
|
if not baymodel:
|
||||||
|
raise OpenStackCloudException(
|
||||||
|
"Baymodel %s not found." % name_or_id)
|
||||||
|
|
||||||
|
if operation not in ['add', 'replace', 'remove']:
|
||||||
|
raise TypeError(
|
||||||
|
"%s operation not in 'add', 'replace', 'remove'" % operation)
|
||||||
|
|
||||||
|
patches = _utils.generate_patches_from_kwargs(operation, **kwargs)
|
||||||
|
|
||||||
|
with _utils.shade_exceptions(
|
||||||
|
"Error updating baymodel {0}".format(name_or_id)):
|
||||||
|
self.manager.submitTask(
|
||||||
|
_tasks.BaymodelUpdate(
|
||||||
|
id=baymodel['id'], patch=patches))
|
||||||
|
|
||||||
|
new_baymodel = self.get_baymodel(name_or_id)
|
||||||
|
return new_baymodel
|
||||||
|
113
shade/tests/functional/test_baymodels.py
Normal file
113
shade/tests/functional/test_baymodels.py
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
# -*- 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')
|
155
shade/tests/unit/test_baymodels.py
Normal file
155
shade/tests/unit/test_baymodels.py
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
# -*- 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'}]
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user