From 7ed28d1c1eea6f6394a412b6a6634a7eb9585753 Mon Sep 17 00:00:00 2001 From: John Griffith Date: Wed, 17 Sep 2014 21:16:18 -0600 Subject: [PATCH] Verify requested size in volume.api create Currently we're not checking that the input value requested for size on volume create is valid, but taskflow portion of the code expects it to be and as a result when it receives invalid input we litter the logs with Trace messages. This patch adds a check that verifies that if we pass in a size to create_volume in the volume.api that it is in fact an int or a string representation of an int. Worst commit ever Change-Id: I81bf515360eacf63e6f3cdb672ec7f37001aa4fb Closes-Bug: 1370773 --- cinder/tests/test_volume.py | 20 ++++++++++++++++++++ cinder/utils.py | 8 ++++++++ cinder/volume/api.py | 16 ++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/cinder/tests/test_volume.py b/cinder/tests/test_volume.py index ca57c7bbec8..468b86fcb48 100644 --- a/cinder/tests/test_volume.py +++ b/cinder/tests/test_volume.py @@ -2303,6 +2303,26 @@ class VolumeTestCase(BaseVolumeTestCase): 'name', 'description') + def test_create_volume_with_float_fails(self): + """Test volume creation with invalid float size.""" + volume_api = cinder.volume.api.API() + self.assertRaises(exception.InvalidInput, + volume_api.create, + self.context, + '1.5', + 'name', + 'description') + + def test_create_volume_with_zero_size_fails(self): + """Test volume creation with string size.""" + volume_api = cinder.volume.api.API() + self.assertRaises(exception.InvalidInput, + volume_api.create, + self.context, + '0', + 'name', + 'description') + def test_begin_detaching_fails_available(self): volume_api = cinder.volume.api.API() volume = tests_utils.create_volume(self.context, **self.volume_params) diff --git a/cinder/utils.py b/cinder/utils.py index 7f7a746d882..1073a20fa99 100644 --- a/cinder/utils.py +++ b/cinder/utils.py @@ -96,6 +96,14 @@ def as_int(obj, quiet=True): return obj +def is_int_like(val): + """Check if a value looks like an int.""" + try: + return str(int(val)) == str(val) + except Exception: + return False + + def check_exclusive_options(**kwargs): """Checks that only one of the provided options is actually not-none. diff --git a/cinder/volume/api.py b/cinder/volume/api.py index e06ee1d08ac..d5f0316bb7a 100644 --- a/cinder/volume/api.py +++ b/cinder/volume/api.py @@ -155,6 +155,22 @@ class API(base.Base): scheduler_hints=None, backup_source_volume=None, source_replica=None, consistencygroup=None): + # NOTE(jdg): we can have a create without size if we're + # doing a create from snap or volume. Currently + # the taskflow api will handle this and pull in the + # size from the source. + + # NOTE(jdg): cinderclient sends in a string representation + # of the size value. BUT there is a possbility that somebody + # could call the API directly so the is_int_like check + # handles both cases (string representation or true float or int). + if size and (not utils.is_int_like(size) or int(size) <= 0): + msg = _('Invalid volume size provided for create request ' + '(size argument must be an integer (or string ' + 'represenation or an integer) and greater ' + 'than zero).') + raise exception.InvalidInput(reason=msg) + if consistencygroup: if not volume_type: msg = _("volume_type must be provided when creating "