Ignore image and flavor validations

Ignore image and flavor validations, if they are not yet
created. This would happen in cases where user with
sufficient privileges have them in the same template
with server.

Change-Id: I3450e85ee85fd40d96bc7d0506db6a2417ffec09
Closes-Bug: #1556317
This commit is contained in:
Rabi Mishra 2016-03-12 06:59:43 +05:30
parent 575af8dfcb
commit eb56cbc8a1
2 changed files with 70 additions and 28 deletions

View File

@ -1280,6 +1280,42 @@ class Server(stack_user.StackUser, sh.SchedulerHintsMixin,
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):
"""Validate any of the provided params."""
super(Server, self).validate()
@ -1299,35 +1335,9 @@ class Server(stack_user.StackUser, sh.SchedulerHintsMixin,
' instance %s') % self.name
raise exception.StackValidationFailed(message=msg)
flavor = self.properties[self.FLAVOR]
if image:
image_obj = self.client_plugin('glance').get_image(image)
# 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)
self._validate_image_flavor(image, flavor)
# network properties 'uuid' and 'network' shouldn't be used
# both at once for all networks

View File

@ -2900,6 +2900,38 @@ class ServersTest(common.HeatTestCase):
six.text_type(error))
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):
stack_name = 'test_stack'
tmpl, stack = self._setup_test_stack(stack_name)