Add and apply cinder backup constraint

Add custom constraint for cinder backup and apply
it to related resources property.

Change-Id: I6e7f0dae98fae6f36b46ca6fcf02f77f79f942dd
Blueprint: add-cinder-backup-constraint
This commit is contained in:
huangtianhua 2015-05-15 16:25:59 +08:00
parent 4e2e6a597d
commit 4b0247dc92
8 changed files with 53 additions and 1 deletions

View File

@ -107,6 +107,15 @@ class CinderClientPlugin(client_plugin.ClientPlugin):
raise exception.EntityNotFound(entity='VolumeSnapshot',
name=snapshot)
def get_volume_backup(self, backup):
try:
return self.client().backups.get(backup)
except exceptions.NotFound as ex:
LOG.info(_LI('Volume backup (%(backup)s) not found: %(ex)s'),
{'backup': backup, 'ex': ex})
raise exception.EntityNotFound(entity='Volume backup',
name=backup)
def get_volume_type(self, volume_type):
vt_id = None
volume_type_list = self.client().volume_types.list()
@ -245,3 +254,11 @@ class VolumeTypeConstraint(constraints.BaseCustomConstraint):
def validate_with_client(self, client, volume_type):
client.client_plugin('cinder').get_volume_type(volume_type)
class VolumeBackupConstraint(constraints.BaseCustomConstraint):
expected_exceptions = (exception.EntityNotFound,)
def validate_with_client(self, client, backup):
client.client_plugin('cinder').get_volume_backup(backup)

View File

@ -50,7 +50,10 @@ class Volume(vb.BaseVolume):
properties.Schema.STRING,
_('If specified, the backup used as the source to create the '
'volume.'),
immutable=True
immutable=True,
constraints=[
constraints.CustomConstraint('cinder.backup')
]
),
TAGS: properties.Schema(
properties.Schema.LIST,

View File

@ -78,6 +78,9 @@ class CinderVolume(vb.BaseVolume):
properties.Schema.STRING,
_('If specified, the backup to create the volume from.'),
update_allowed=True,
constraints=[
constraints.CustomConstraint('cinder.backup')
]
),
NAME: properties.Schema(
properties.Schema.STRING,

View File

@ -612,6 +612,7 @@ class VolumeTest(vt_base.BaseVolumeTest):
# create script
cinder.CinderClientPlugin._create().AndReturn(
self.cinder_fc)
self.patchobject(self.cinder_fc.backups, 'get')
self.m.StubOutWithMock(self.cinder_fc.restores, 'restore')
self.cinder_fc.restores.restore('backup-123').AndReturn(fvbr)
self.cinder_fc.volumes.get('vol-123').AndReturn(fv)
@ -640,6 +641,7 @@ class VolumeTest(vt_base.BaseVolumeTest):
# create script
cinder.CinderClientPlugin._create().AndReturn(
self.cinder_fc)
self.patchobject(self.cinder_fc.backups, 'get')
self.m.StubOutWithMock(self.cinder_fc.restores, 'restore')
self.cinder_fc.restores.restore('backup-123').AndReturn(fvbr)
self.cinder_fc.volumes.get('vol-123').AndReturn(fv)

View File

@ -489,6 +489,7 @@ class CinderVolumeTest(vt_base.BaseVolumeTest):
stack_name = 'test_cvolume_extend_snapsht_stack'
# create script
self.stub_VolumeBackupConstraint_validate()
fvbr = vt_base.FakeBackupRestore('vol-123')
cinder.CinderClientPlugin._create().MultipleTimes().AndReturn(
self.cinder_fc)
@ -1010,6 +1011,7 @@ class CinderVolumeTest(vt_base.BaseVolumeTest):
).AndReturn(vt_base.FakeVolume('creating'))
fv = vt_base.FakeVolume('available')
self.cinder_fc.volumes.get(fv.id).AndReturn(fv)
self.stub_VolumeBackupConstraint_validate()
# snapshot script
fb = vt_base.FakeBackup('creating')

View File

@ -114,3 +114,23 @@ class VolumeTypeConstraintTest(common.HeatTestCase):
self.mock_get_volume_type.side_effect = exception.EntityNotFound(
entity='VolumeType', name='bar')
self.assertFalse(self.constraint.validate("bar", self.ctx))
class VolumeBackupConstraintTest(common.HeatTestCase):
def setUp(self):
super(VolumeBackupConstraintTest, self).setUp()
self.ctx = utils.dummy_context()
self.mock_get_volume_backup = mock.Mock()
self.ctx.clients.client_plugin(
'cinder').get_volume_backup = self.mock_get_volume_backup
self.constraint = cinder.VolumeBackupConstraint()
def test_validation(self):
self.mock_get_volume_backup.return_value = 'volume_backup'
self.assertTrue(self.constraint.validate("foo", self.ctx))
def test_validation_error(self):
ex = exception.EntityNotFound(entity='Volume backup', name='bar')
self.mock_get_volume_backup.side_effect = ex
self.assertFalse(self.constraint.validate("bar", self.ctx))

View File

@ -216,6 +216,10 @@ class HeatTestCase(testscenarios.WithScenarios,
validate = self.patchobject(cinder.VolumeTypeConstraint, 'validate')
validate.return_value = True
def stub_VolumeBackupConstraint_validate(self):
validate = self.patchobject(cinder.VolumeBackupConstraint, 'validate')
validate.return_value = True
def stub_ServerConstraint_validate(self):
validate = self.patchobject(nova.ServerConstraint, 'validate')
validate.return_value = True

View File

@ -79,6 +79,7 @@ heat.constraints =
cinder.volume = heat.engine.clients.os.cinder:VolumeConstraint
cinder.snapshot = heat.engine.clients.os.cinder:VolumeSnapshotConstraint
cinder.vtype = heat.engine.clients.os.cinder:VolumeTypeConstraint
cinder.backup = heat.engine.clients.os.cinder:VolumeBackupConstraint
sahara.image = heat.engine.clients.os.sahara:ImageConstraint
trove.flavor = heat.engine.clients.os.trove:FlavorConstraint
ip_addr = heat.engine.constraint.common_constraints:IPConstraint