Allow image and flavor by name for create_server
We do a bunch of work everywhere else in shade to be friendly - but for some reason we only accept object or id for image and flavor. Fix it. In the unit tests, pass in a dict with an id value to avoid the need to mock the glance client, since that's not really what we're testing in any of those tests ... but add a test that does not do that to verify that the glance and nova clients are used to look at image/flavor lists. Change-Id: I1760a7464e43e19a475f6d277148a3c7e54ac468
This commit is contained in:
parent
79d87718d9
commit
4e7772632a
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- The image and flavor parameters for create_server
|
||||||
|
now accept name in addition to id and dict. If given
|
||||||
|
as a name or id, shade will do a get_image or a
|
||||||
|
get_flavor to find the matching image or flavor.
|
||||||
|
If you have an id already and are not using any caching
|
||||||
|
and the extra lookup is annoying, passing the id in
|
||||||
|
as "dict(id='my-id')" will avoid the lookup.
|
@ -4194,8 +4194,8 @@ class OpenStackCloud(object):
|
|||||||
"""Create a virtual server instance.
|
"""Create a virtual server instance.
|
||||||
|
|
||||||
:param name: Something to name the server.
|
:param name: Something to name the server.
|
||||||
:param image: Image dict or id to boot with.
|
:param image: Image dict, name or id to boot with.
|
||||||
:param flavor: Flavor dict or id to boot onto.
|
:param flavor: Flavor dict, name or id to boot onto.
|
||||||
:param auto_ip: Whether to take actions to find a routable IP for
|
:param auto_ip: Whether to take actions to find a routable IP for
|
||||||
the server. (defaults to True)
|
the server. (defaults to True)
|
||||||
:param ips: List of IPs to attach to the server (defaults to None)
|
:param ips: List of IPs to attach to the server (defaults to None)
|
||||||
@ -4300,7 +4300,15 @@ class OpenStackCloud(object):
|
|||||||
if default_network:
|
if default_network:
|
||||||
kwargs['nics'] = [{'net-id': default_network['id']}]
|
kwargs['nics'] = [{'net-id': default_network['id']}]
|
||||||
|
|
||||||
|
if image:
|
||||||
|
if isinstance(image, dict):
|
||||||
kwargs['image'] = image
|
kwargs['image'] = image
|
||||||
|
else:
|
||||||
|
kwargs['image'] = self.get_image(image)
|
||||||
|
if flavor and isinstance(flavor, dict):
|
||||||
|
kwargs['flavor'] = flavor
|
||||||
|
else:
|
||||||
|
kwargs['flavor'] = self.get_flavor(flavor, get_extra=False)
|
||||||
|
|
||||||
kwargs = self._get_boot_from_volume_kwargs(
|
kwargs = self._get_boot_from_volume_kwargs(
|
||||||
image=image, boot_from_volume=boot_from_volume,
|
image=image, boot_from_volume=boot_from_volume,
|
||||||
@ -4310,7 +4318,7 @@ class OpenStackCloud(object):
|
|||||||
|
|
||||||
with _utils.shade_exceptions("Error in creating instance"):
|
with _utils.shade_exceptions("Error in creating instance"):
|
||||||
server = self.manager.submitTask(_tasks.ServerCreate(
|
server = self.manager.submitTask(_tasks.ServerCreate(
|
||||||
name=name, flavor=flavor, **kwargs))
|
name=name, **kwargs))
|
||||||
admin_pass = server.get('adminPass') or kwargs.get('admin_pass')
|
admin_pass = server.get('adminPass') or kwargs.get('admin_pass')
|
||||||
if not wait:
|
if not wait:
|
||||||
# This is a direct get task call to skip the list_servers
|
# This is a direct get task call to skip the list_servers
|
||||||
|
@ -99,7 +99,8 @@ class TestCreateServer(base.TestCase):
|
|||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
OpenStackCloudException,
|
OpenStackCloudException,
|
||||||
self.cloud.create_server,
|
self.cloud.create_server,
|
||||||
'server-name', 'image-id', 'flavor-id', wait=True)
|
'server-name', dict(id='image-id'),
|
||||||
|
dict(id='flavor-id'), wait=True)
|
||||||
|
|
||||||
def test_create_server_with_timeout(self):
|
def test_create_server_with_timeout(self):
|
||||||
"""
|
"""
|
||||||
@ -117,7 +118,8 @@ class TestCreateServer(base.TestCase):
|
|||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
OpenStackCloudTimeout,
|
OpenStackCloudTimeout,
|
||||||
self.cloud.create_server,
|
self.cloud.create_server,
|
||||||
'server-name', 'image-id', 'flavor-id',
|
'server-name',
|
||||||
|
dict(id='image-id'), dict(id='flavor-id'),
|
||||||
wait=True, timeout=0.01)
|
wait=True, timeout=0.01)
|
||||||
|
|
||||||
def test_create_server_no_wait(self):
|
def test_create_server_no_wait(self):
|
||||||
@ -142,8 +144,9 @@ class TestCreateServer(base.TestCase):
|
|||||||
cloud_name=self.cloud.name,
|
cloud_name=self.cloud.name,
|
||||||
region_name=self.cloud.region_name),
|
region_name=self.cloud.region_name),
|
||||||
self.cloud.create_server(
|
self.cloud.create_server(
|
||||||
name='server-name', image='image=id',
|
name='server-name',
|
||||||
flavor='flavor-id'))
|
image=dict(id='image=id'),
|
||||||
|
flavor=dict(id='flavor-id')))
|
||||||
|
|
||||||
def test_create_server_with_admin_pass_no_wait(self):
|
def test_create_server_with_admin_pass_no_wait(self):
|
||||||
"""
|
"""
|
||||||
@ -168,8 +171,8 @@ class TestCreateServer(base.TestCase):
|
|||||||
cloud_name=self.cloud.name,
|
cloud_name=self.cloud.name,
|
||||||
region_name=self.cloud.region_name),
|
region_name=self.cloud.region_name),
|
||||||
self.cloud.create_server(
|
self.cloud.create_server(
|
||||||
name='server-name', image='image=id',
|
name='server-name', image=dict(id='image=id'),
|
||||||
flavor='flavor-id', admin_pass='ooBootheiX0edoh'))
|
flavor=dict(id='flavor-id'), admin_pass='ooBootheiX0edoh'))
|
||||||
|
|
||||||
@patch.object(OpenStackCloud, "wait_for_server")
|
@patch.object(OpenStackCloud, "wait_for_server")
|
||||||
@patch.object(OpenStackCloud, "nova_client")
|
@patch.object(OpenStackCloud, "nova_client")
|
||||||
@ -188,8 +191,9 @@ class TestCreateServer(base.TestCase):
|
|||||||
meta.obj_to_dict(fake_server), None, None)
|
meta.obj_to_dict(fake_server), None, None)
|
||||||
|
|
||||||
server = self.cloud.create_server(
|
server = self.cloud.create_server(
|
||||||
name='server-name', image='image-id',
|
name='server-name', image=dict(id='image-id'),
|
||||||
flavor='flavor-id', admin_pass='ooBootheiX0edoh', wait=True)
|
flavor=dict(id='flavor-id'),
|
||||||
|
admin_pass='ooBootheiX0edoh', wait=True)
|
||||||
|
|
||||||
# Assert that we did wait
|
# Assert that we did wait
|
||||||
self.assertTrue(mock_wait.called)
|
self.assertTrue(mock_wait.called)
|
||||||
@ -245,7 +249,8 @@ class TestCreateServer(base.TestCase):
|
|||||||
mock_nova.servers.create.return_value = fake_server
|
mock_nova.servers.create.return_value = fake_server
|
||||||
|
|
||||||
self.cloud.create_server(
|
self.cloud.create_server(
|
||||||
'server-name', 'image-id', 'flavor-id', wait=True),
|
'server-name',
|
||||||
|
dict(id='image-id'), dict(id='flavor-id'), wait=True),
|
||||||
|
|
||||||
mock_wait.assert_called_once_with(
|
mock_wait.assert_called_once_with(
|
||||||
fake_server, auto_ip=True, ips=None,
|
fake_server, auto_ip=True, ips=None,
|
||||||
@ -291,7 +296,8 @@ class TestCreateServer(base.TestCase):
|
|||||||
attempt to get the network for the server.
|
attempt to get the network for the server.
|
||||||
"""
|
"""
|
||||||
self.cloud.create_server(
|
self.cloud.create_server(
|
||||||
'server-name', 'image-id', 'flavor-id', network='network-name')
|
'server-name',
|
||||||
|
dict(id='image-id'), dict(id='flavor-id'), network='network-name')
|
||||||
mock_get_network.assert_called_once_with(name_or_id='network-name')
|
mock_get_network.assert_called_once_with(name_or_id='network-name')
|
||||||
|
|
||||||
@patch('shade.OpenStackCloud.nova_client')
|
@patch('shade.OpenStackCloud.nova_client')
|
||||||
@ -304,6 +310,15 @@ class TestCreateServer(base.TestCase):
|
|||||||
it's treated the same as if 'nics' were not included.
|
it's treated the same as if 'nics' were not included.
|
||||||
"""
|
"""
|
||||||
self.cloud.create_server(
|
self.cloud.create_server(
|
||||||
'server-name', 'image-id', 'flavor-id',
|
'server-name', dict(id='image-id'), dict(id='flavor-id'),
|
||||||
network='network-name', nics=[])
|
network='network-name', nics=[])
|
||||||
mock_get_network.assert_called_once_with(name_or_id='network-name')
|
mock_get_network.assert_called_once_with(name_or_id='network-name')
|
||||||
|
|
||||||
|
@patch('shade.OpenStackCloud.glance_client')
|
||||||
|
@patch('shade.OpenStackCloud.nova_client')
|
||||||
|
def test_create_server_get_flavor_image(
|
||||||
|
self, mock_nova, mock_glance):
|
||||||
|
self.cloud.create_server(
|
||||||
|
'server-name', 'image-id', 'flavor-id')
|
||||||
|
mock_nova.flavors.list.assert_called_once()
|
||||||
|
mock_glance.images.list.assert_called_once()
|
||||||
|
Loading…
Reference in New Issue
Block a user