Merge "Ignore image and flavor validations"
This commit is contained in:
commit
5748507573
@ -1280,6 +1280,42 @@ class Server(stack_user.StackUser, sh.SchedulerHintsMixin,
|
|||||||
|
|
||||||
return bootable_vol
|
return bootable_vol
|
||||||
|
|
||||||
|
def _validate_image_flavor(self, image, flavor):
|
||||||
|
try:
|
||||||
|
image_obj = self.client_plugin('glance').get_image(image)
|
||||||
|
flavor_obj = self.client_plugin().get_flavor(flavor)
|
||||||
|
except Exception as ex:
|
||||||
|
# Flavor or image may not have been created in the backend
|
||||||
|
# yet when they are part of the same stack/template.
|
||||||
|
if (self.client_plugin().is_not_found(ex) or
|
||||||
|
self.client_plugin('glance').is_not_found(ex)):
|
||||||
|
return
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
if image_obj.status.lower() != self.IMAGE_STATUS_ACTIVE:
|
||||||
|
msg = _('Image status is required to be %(cstatus)s not '
|
||||||
|
'%(wstatus)s.') % {
|
||||||
|
'cstatus': self.IMAGE_STATUS_ACTIVE,
|
||||||
|
'wstatus': image_obj.status}
|
||||||
|
raise exception.StackValidationFailed(message=msg)
|
||||||
|
|
||||||
|
# validate image/flavor combination
|
||||||
|
if flavor_obj.ram < image_obj.min_ram:
|
||||||
|
msg = _('Image %(image)s requires %(imram)s minimum ram. '
|
||||||
|
'Flavor %(flavor)s has only %(flram)s.') % {
|
||||||
|
'image': image, 'imram': image_obj.min_ram,
|
||||||
|
'flavor': flavor, 'flram': flavor_obj.ram}
|
||||||
|
raise exception.StackValidationFailed(message=msg)
|
||||||
|
|
||||||
|
# validate image/flavor disk compatibility
|
||||||
|
if flavor_obj.disk < image_obj.min_disk:
|
||||||
|
msg = _('Image %(image)s requires %(imsz)s GB minimum '
|
||||||
|
'disk space. Flavor %(flavor)s has only '
|
||||||
|
'%(flsz)s GB.') % {
|
||||||
|
'image': image, 'imsz': image_obj.min_disk,
|
||||||
|
'flavor': flavor, 'flsz': flavor_obj.disk}
|
||||||
|
raise exception.StackValidationFailed(message=msg)
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
"""Validate any of the provided params."""
|
"""Validate any of the provided params."""
|
||||||
super(Server, self).validate()
|
super(Server, self).validate()
|
||||||
@ -1299,35 +1335,9 @@ class Server(stack_user.StackUser, sh.SchedulerHintsMixin,
|
|||||||
' instance %s') % self.name
|
' instance %s') % self.name
|
||||||
raise exception.StackValidationFailed(message=msg)
|
raise exception.StackValidationFailed(message=msg)
|
||||||
|
|
||||||
|
flavor = self.properties[self.FLAVOR]
|
||||||
if image:
|
if image:
|
||||||
image_obj = self.client_plugin('glance').get_image(image)
|
self._validate_image_flavor(image, flavor)
|
||||||
|
|
||||||
# validate image status
|
|
||||||
if image_obj.status.lower() != self.IMAGE_STATUS_ACTIVE:
|
|
||||||
msg = _('Image status is required to be %(cstatus)s not '
|
|
||||||
'%(wstatus)s.') % {
|
|
||||||
'cstatus': self.IMAGE_STATUS_ACTIVE,
|
|
||||||
'wstatus': image_obj.status}
|
|
||||||
raise exception.StackValidationFailed(message=msg)
|
|
||||||
|
|
||||||
# validate image/flavor combination
|
|
||||||
flavor = self.properties[self.FLAVOR]
|
|
||||||
flavor_obj = self.client_plugin().get_flavor(flavor)
|
|
||||||
if flavor_obj.ram < image_obj.min_ram:
|
|
||||||
msg = _('Image %(image)s requires %(imram)s minimum ram. '
|
|
||||||
'Flavor %(flavor)s has only %(flram)s.') % {
|
|
||||||
'image': image, 'imram': image_obj.min_ram,
|
|
||||||
'flavor': flavor, 'flram': flavor_obj.ram}
|
|
||||||
raise exception.StackValidationFailed(message=msg)
|
|
||||||
|
|
||||||
# validate image/flavor disk compatibility
|
|
||||||
if flavor_obj.disk < image_obj.min_disk:
|
|
||||||
msg = _('Image %(image)s requires %(imsz)s GB minimum '
|
|
||||||
'disk space. Flavor %(flavor)s has only '
|
|
||||||
'%(flsz)s GB.') % {
|
|
||||||
'image': image, 'imsz': image_obj.min_disk,
|
|
||||||
'flavor': flavor, 'flsz': flavor_obj.disk}
|
|
||||||
raise exception.StackValidationFailed(message=msg)
|
|
||||||
|
|
||||||
# network properties 'uuid' and 'network' shouldn't be used
|
# network properties 'uuid' and 'network' shouldn't be used
|
||||||
# both at once for all networks
|
# both at once for all networks
|
||||||
|
@ -2900,6 +2900,38 @@ class ServersTest(common.HeatTestCase):
|
|||||||
six.text_type(error))
|
six.text_type(error))
|
||||||
self.m.VerifyAll()
|
self.m.VerifyAll()
|
||||||
|
|
||||||
|
def test_validate_image_flavor_not_found(self):
|
||||||
|
stack_name = 'test_stack'
|
||||||
|
tmpl, stack = self._setup_test_stack(stack_name)
|
||||||
|
|
||||||
|
resource_defns = tmpl.resource_definitions(stack)
|
||||||
|
server = servers.Server('image_not_found',
|
||||||
|
resource_defns['WebServer'], stack)
|
||||||
|
|
||||||
|
self._server_validate_mock(server)
|
||||||
|
image = tmpl['Resources']['WebServer']['Properties']['image']
|
||||||
|
flavor = tmpl['Resources']['WebServer']['Properties']['flavor']
|
||||||
|
|
||||||
|
self.m.StubOutWithMock(glance.GlanceClientPlugin, 'get_image')
|
||||||
|
self.m.StubOutWithMock(nova.NovaClientPlugin, 'get_flavor')
|
||||||
|
|
||||||
|
self.stub_FlavorConstraint_validate()
|
||||||
|
# Image not found
|
||||||
|
glance.GlanceClientPlugin.get_image(
|
||||||
|
image).AndRaise(glance.exceptions.NotFound())
|
||||||
|
|
||||||
|
# Flavor not found
|
||||||
|
glance.GlanceClientPlugin.get_image(
|
||||||
|
image).AndReturn(self.mock_image)
|
||||||
|
nova.NovaClientPlugin.get_flavor(
|
||||||
|
flavor).AndRaise(fakes_nova.fake_exception())
|
||||||
|
self.m.ReplayAll()
|
||||||
|
|
||||||
|
self.assertIsNone(server.validate())
|
||||||
|
|
||||||
|
self.assertIsNone(server.validate())
|
||||||
|
self.m.VerifyAll()
|
||||||
|
|
||||||
def test_validate_insufficient_disk_flavor(self):
|
def test_validate_insufficient_disk_flavor(self):
|
||||||
stack_name = 'test_stack'
|
stack_name = 'test_stack'
|
||||||
tmpl, stack = self._setup_test_stack(stack_name)
|
tmpl, stack = self._setup_test_stack(stack_name)
|
||||||
|
Loading…
Reference in New Issue
Block a user