| 
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