From 48bb13ed71bf14e64c5201f8ed8f1d8595ffa676 Mon Sep 17 00:00:00 2001 From: Walter Boring IV Date: Wed, 27 Sep 2023 16:42:01 -0400 Subject: [PATCH] SAP: Add affinity UUID validation This patch adds some basic UUID volume validation for the cinder create volume API request when passing in scheduler hints for volume affinity or anti-affinity. The API now ensures that the UUIDs are valid cinder volumes. The UUID must be a valid cinder volume UUID for the create call to work. --- cinder/volume/api.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/cinder/volume/api.py b/cinder/volume/api.py index f0f63f8fc91..22abee0a443 100644 --- a/cinder/volume/api.py +++ b/cinder/volume/api.py @@ -26,6 +26,7 @@ from oslo_utils import excutils from oslo_utils import strutils from oslo_utils import timeutils +from oslo_utils import uuidutils from oslo_utils import versionutils from cinder import action_track @@ -298,6 +299,37 @@ def create(self, context, size, name, description, snapshot=None, if CONF.storage_availability_zone: availability_zones.add(CONF.storage_availability_zone) + # Validate the scheduler_hints same_host and different_hosts as + # valid volume UUIDs. + if scheduler_hints: + validate_volume_uuids = [] + if 'same_host' in scheduler_hints: + if isinstance(scheduler_hints['same_host'], list): + validate_volume_uuids.extend(scheduler_hints['same_host']) + else: + validate_volume_uuids.append(scheduler_hints['same_host']) + elif 'different_host' in scheduler_hints: + if isinstance(scheduler_hints['different_host'], list): + validate_volume_uuids.extend( + scheduler_hints['different_host']) + else: + validate_volume_uuids.append( + scheduler_hints['different_host']) + + for hint_volume_id in validate_volume_uuids: + if not uuidutils.is_uuid_like(hint_volume_id): + msg = _("Invalid UUID(s) '%s' provided in scheduler " + "hints.") % hint_volume_id + raise exception.InvalidInput(reason=msg) + + # Now validate that the uuids are valid volumes that exist in + # cinder DB. + for hint_volume_id in validate_volume_uuids: + # All we have to do here is try and fetch the UUID as volume. + # If the UUID doesn't exist in the DB, Cinder will throw + # a VolumeNotFound exception. + objects.Volume.get_by_id(context, hint_volume_id) + # Force the scheduler hints into the volume metadata if not metadata: metadata = {}