|
26 | 26 | from oslo_utils import excutils |
27 | 27 | from oslo_utils import strutils |
28 | 28 | from oslo_utils import timeutils |
| 29 | +from oslo_utils import uuidutils |
29 | 30 | from oslo_utils import versionutils |
30 | 31 |
|
31 | 32 | from cinder import action_track |
@@ -204,6 +205,36 @@ def _is_encrypted(self, volume_type): |
204 | 205 | return False |
205 | 206 | return specs.get('encryption', {}) is not {} |
206 | 207 |
|
| 208 | + def _validate_scheduler_hints(self, scheduler_hints): |
| 209 | + if scheduler_hints: |
| 210 | + validate_volume_uuids = [] |
| 211 | + if 'same_host' in scheduler_hints: |
| 212 | + if isinstance(scheduler_hints['same_host'], list): |
| 213 | + validate_volume_uuids.extend(scheduler_hints['same_host']) |
| 214 | + else: |
| 215 | + validate_volume_uuids.append(scheduler_hints['same_host']) |
| 216 | + elif 'different_host' in scheduler_hints: |
| 217 | + if isinstance(scheduler_hints['different_host'], list): |
| 218 | + validate_volume_uuids.extend( |
| 219 | + scheduler_hints['different_host']) |
| 220 | + else: |
| 221 | + validate_volume_uuids.append( |
| 222 | + scheduler_hints['different_host']) |
| 223 | + |
| 224 | + for hint_volume_id in validate_volume_uuids: |
| 225 | + if not uuidutils.is_uuid_like(hint_volume_id): |
| 226 | + msg = _("Invalid UUID(s) '%s' provided in scheduler " |
| 227 | + "hints.") % hint_volume_id |
| 228 | + raise exception.InvalidInput(reason=msg) |
| 229 | + |
| 230 | + # Now validate that the uuids are valid volumes that exist in |
| 231 | + # cinder DB. |
| 232 | + for hint_volume_id in validate_volume_uuids: |
| 233 | + # All we have to do here is try and fetch the UUID as volume. |
| 234 | + # If the UUID doesn't exist in the DB, Cinder will throw |
| 235 | + # a VolumeNotFound exception. |
| 236 | + objects.Volume.get_by_id(context, hint_volume_id) |
| 237 | + |
207 | 238 | @action_track.track_decorator(action_track.ACTION_VOLUME_CREATE) |
208 | 239 | def create(self, context, size, name, description, snapshot=None, |
209 | 240 | image_id=None, volume_type=None, metadata=None, |
@@ -298,6 +329,10 @@ def create(self, context, size, name, description, snapshot=None, |
298 | 329 | if CONF.storage_availability_zone: |
299 | 330 | availability_zones.add(CONF.storage_availability_zone) |
300 | 331 |
|
| 332 | + # Validate the scheduler_hints same_host and different_hosts as |
| 333 | + # valid volume UUIDs. |
| 334 | + self._validate_scheduler_hints(scheduler_hints) |
| 335 | + |
301 | 336 | # Force the scheduler hints into the volume metadata |
302 | 337 | if not metadata: |
303 | 338 | metadata = {} |
|
0 commit comments