def _check_type(self, group): if not vol_utils.is_group_a_replication_group_type(group): msg = _("Group %s is not a replication group type.") % group.id LOG.error(msg) raise exception.InvalidGroupType(reason=msg) for vol_type in group.volume_types: if not vol_utils.is_replicated_spec(vol_type.extra_specs): msg = _("Volume type %s does not have 'replication_enabled' " "spec key set to '<is> True'.") % vol_type.id LOG.error(msg) raise exception.InvalidVolumeType(reason=msg)
def create_volume(self, volume): """Creates a volume.""" super(FakeLoggingVolumeDriver, self).create_volume(volume) model_update = {} try: if (volume.volume_type and volume.volume_type.extra_specs and vol_utils.is_replicated_spec( volume.volume_type.extra_specs)): # Sets the new volume's replication_status to disabled model_update['replication_status'] = ( fields.ReplicationStatus.DISABLED) except exception.VolumeTypeNotFound: pass if model_update: return model_update
def create_volume(self, volume): """Creates a volume.""" super(FakeLoggingVolumeDriver, self).create_volume(volume) model_update = {} try: if (volume.volume_type and volume.volume_type.extra_specs and vol_utils.is_replicated_spec( volume.volume_type.extra_specs)): # Sets the new volume's replication_status to disabled model_update['replication_status'] = ( fields.ReplicationStatus.DISABLED) except exception.VolumeTypeNotFound: pass if model_update: return model_update
def execute(self, context, size, snapshot, image_id, source_volume, availability_zone, volume_type, metadata, key_manager, consistencygroup, cgsnapshot, group): utils.check_exclusive_options(snapshot=snapshot, imageRef=image_id, source_volume=source_volume) policy.enforce_action(context, ACTION) # TODO(harlowja): what guarantee is there that the snapshot or source # volume will remain available after we do this initial verification?? snapshot_id = self._extract_snapshot(snapshot) source_volid = self._extract_source_volume(source_volume) size = self._extract_size(size, source_volume, snapshot) consistencygroup_id = self._extract_consistencygroup(consistencygroup) cgsnapshot_id = self._extract_cgsnapshot(cgsnapshot) group_id = self._extract_group(group) image_meta = self._get_image_metadata(context, image_id, size) availability_zone, refresh_az = self._extract_availability_zone( availability_zone, snapshot, source_volume, group) # TODO(joel-coffman): This special handling of snapshots to ensure that # their volume type matches the source volume is too convoluted. We # should copy encryption metadata from the encrypted volume type to the # volume upon creation and propagate that information to each snapshot. # This strategy avoids any dependency upon the encrypted volume type. def_vol_type = volume_types.get_default_volume_type() if not volume_type and not source_volume and not snapshot: image_volume_type = self._get_image_volume_type(context, image_id) volume_type = (image_volume_type if image_volume_type else def_vol_type) volume_type_id = self._get_volume_type_id(volume_type, source_volume, snapshot) encryption_key_id = self._get_encryption_key_id( key_manager, context, volume_type_id, snapshot, source_volume, image_meta) specs = {} if volume_type_id: qos_specs = volume_types.get_volume_type_qos_specs(volume_type_id) if qos_specs['qos_specs']: specs = qos_specs['qos_specs'].get('specs', {}) # Determine default replication status extra_specs = volume_types.get_volume_type_extra_specs( volume_type_id) if not specs: # to make sure we don't pass empty dict specs = None extra_specs = None if vol_utils.is_replicated_spec(extra_specs): replication_status = fields.ReplicationStatus.ENABLED else: replication_status = fields.ReplicationStatus.DISABLED return { 'size': size, 'snapshot_id': snapshot_id, 'source_volid': source_volid, 'availability_zone': availability_zone, 'volume_type': volume_type, 'volume_type_id': volume_type_id, 'encryption_key_id': encryption_key_id, 'qos_specs': specs, 'consistencygroup_id': consistencygroup_id, 'cgsnapshot_id': cgsnapshot_id, 'group_id': group_id, 'replication_status': replication_status, 'refresh_az': refresh_az }
def execute(self, context, size, snapshot, image_id, source_volume, availability_zone, volume_type, metadata, key_manager, consistencygroup, cgsnapshot, group, group_snapshot, backup, multiattach=False): utils.check_exclusive_options(snapshot=snapshot, imageRef=image_id, source_volume=source_volume, backup=backup) context.authorize(policy.CREATE_POLICY) # TODO(harlowja): what guarantee is there that the snapshot or source # volume will remain available after we do this initial verification?? snapshot_id = self._extract_snapshot(snapshot) source_volid = self._extract_source_volume(source_volume) backup_id = self._extract_backup(backup) size = self._extract_size(size, source_volume, snapshot, backup) consistencygroup_id = self._extract_consistencygroup(consistencygroup) cgsnapshot_id = self._extract_cgsnapshot(cgsnapshot) group_id = self._extract_group(group) image_meta = self._get_image_metadata(context, image_id, size) image_properties = image_meta.get('properties', {}) if image_meta else {} image_volume_type = image_properties.get( 'cinder_img_volume_type', None) if image_properties else None volume_type = self._get_volume_type(context, volume_type, source_volume, snapshot, image_volume_type) volume_type_id = volume_type.get('id') if volume_type else None availability_zones, refresh_az = self._extract_availability_zones( availability_zone, snapshot, source_volume, group, volume_type=volume_type) encryption_key_id = self._get_encryption_key_id( key_manager, context, volume_type_id, snapshot, source_volume, image_meta) if volume_type_id: volume_type = objects.VolumeType.get_by_name_or_id( context, volume_type_id) extra_specs = volume_type.get('extra_specs', {}) # NOTE(tommylikehu): Although the parameter `multiattach` from # create volume API is deprecated now, we still need to consider # it when multiattach is not enabled in volume type. multiattach = (extra_specs.get('multiattach', '') == '<is> True' or multiattach) if multiattach and encryption_key_id: msg = _('Multiattach cannot be used with encrypted volumes.') raise exception.InvalidVolume(reason=msg) if multiattach: context.authorize(policy.MULTIATTACH_POLICY) specs = {} if volume_type_id: qos_specs = volume_types.get_volume_type_qos_specs(volume_type_id) if qos_specs['qos_specs']: specs = qos_specs['qos_specs'].get('specs', {}) # Determine default replication status extra_specs = volume_types.get_volume_type_extra_specs( volume_type_id) if not specs: # to make sure we don't pass empty dict specs = None extra_specs = None if vol_utils.is_replicated_spec(extra_specs): replication_status = fields.ReplicationStatus.ENABLED else: replication_status = fields.ReplicationStatus.DISABLED return { 'size': size, 'snapshot_id': snapshot_id, 'source_volid': source_volid, 'volume_type': volume_type, 'volume_type_id': volume_type_id, 'encryption_key_id': encryption_key_id, 'qos_specs': specs, 'consistencygroup_id': consistencygroup_id, 'cgsnapshot_id': cgsnapshot_id, 'group_id': group_id, 'replication_status': replication_status, 'refresh_az': refresh_az, 'backup_id': backup_id, 'multiattach': multiattach, 'availability_zones': availability_zones }
def test_is_replicated_spec_false(self, enabled): res = volume_utils.is_replicated_spec({'replication_enabled': enabled}) self.assertFalse(res)
def execute(self, context, size, snapshot, image_id, source_volume, availability_zone, volume_type, metadata, key_manager, consistencygroup, cgsnapshot, group, group_snapshot, backup, multiattach=False): utils.check_exclusive_options(snapshot=snapshot, imageRef=image_id, source_volume=source_volume, backup=backup) context.authorize(policy.CREATE_POLICY) # TODO(harlowja): what guarantee is there that the snapshot or source # volume will remain available after we do this initial verification?? snapshot_id = self._extract_snapshot(snapshot) source_volid = self._extract_source_volume(source_volume) backup_id = self._extract_backup(backup) size = self._extract_size(size, source_volume, snapshot, backup) consistencygroup_id = self._extract_consistencygroup(consistencygroup) cgsnapshot_id = self._extract_cgsnapshot(cgsnapshot) group_id = self._extract_group(group) image_meta = self._get_image_metadata(context, image_id, size) image_properties = image_meta.get( 'properties', {}) if image_meta else {} image_volume_type = image_properties.get( 'cinder_img_volume_type', None) if image_properties else None volume_type = self._get_volume_type( context, volume_type, source_volume, snapshot, image_volume_type) volume_type_id = volume_type.get('id') if volume_type else None availability_zones, refresh_az = self._extract_availability_zones( availability_zone, snapshot, source_volume, group, volume_type=volume_type) encryption_key_id = self._get_encryption_key_id( key_manager, context, volume_type_id, snapshot, source_volume, image_meta) if volume_type_id: volume_type = objects.VolumeType.get_by_name_or_id( context, volume_type_id) extra_specs = volume_type.get('extra_specs', {}) # NOTE(tommylikehu): Although the parameter `multiattach` from # create volume API is deprecated now, we still need to consider # it when multiattach is not enabled in volume type. multiattach = (extra_specs.get( 'multiattach', '') == '<is> True' or multiattach) if multiattach and encryption_key_id: msg = _('Multiattach cannot be used with encrypted volumes.') raise exception.InvalidVolume(reason=msg) if multiattach: context.authorize(policy.MULTIATTACH_POLICY) specs = {} if volume_type_id: qos_specs = volume_types.get_volume_type_qos_specs(volume_type_id) if qos_specs['qos_specs']: specs = qos_specs['qos_specs'].get('specs', {}) # Determine default replication status extra_specs = volume_types.get_volume_type_extra_specs( volume_type_id) if not specs: # to make sure we don't pass empty dict specs = None extra_specs = None if vol_utils.is_replicated_spec(extra_specs): replication_status = fields.ReplicationStatus.ENABLED else: replication_status = fields.ReplicationStatus.DISABLED return { 'size': size, 'snapshot_id': snapshot_id, 'source_volid': source_volid, 'volume_type': volume_type, 'volume_type_id': volume_type_id, 'encryption_key_id': encryption_key_id, 'qos_specs': specs, 'consistencygroup_id': consistencygroup_id, 'cgsnapshot_id': cgsnapshot_id, 'group_id': group_id, 'replication_status': replication_status, 'refresh_az': refresh_az, 'backup_id': backup_id, 'multiattach': multiattach, 'availability_zones': availability_zones }
def test_is_replicated_no_specs(self, extra_specs): res = volume_utils.is_replicated_spec(extra_specs) self.assertFalse(res)
def is_replicated(self): return utils.is_replicated_spec(self.extra_specs)
def is_replicated(self): return utils.is_replicated_spec(self.extra_specs)
def test_is_replicated_spec_false(self, enabled): res = volume_utils.is_replicated_spec({'replication_enabled': enabled}) self.assertFalse(res)
def test_is_replicated_no_specs(self, extra_specs): res = volume_utils.is_replicated_spec(extra_specs) self.assertFalse(bool(res))