summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/api/ec2/__init__.py4
-rw-r--r--nova/api/ec2/cloud.py42
-rw-r--r--nova/tests/test_api.py48
3 files changed, 69 insertions, 25 deletions
diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py
index 33a5c4af4..3a1fa238a 100644
--- a/nova/api/ec2/__init__.py
+++ b/nova/api/ec2/__init__.py
@@ -62,6 +62,10 @@ ec2_opts = [
default=False,
help='Return the IP address as private dns hostname in '
'describe instances'),
+ cfg.BoolOpt('ec2_strict_validation',
+ default=True,
+ help='Validate security group names'
+ ' according to EC2 specification'),
]
FLAGS = flags.FLAGS
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index 13c91cf19..43686aa12 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -759,18 +759,36 @@ class CloudController(object):
return source_project_id
def create_security_group(self, context, group_name, group_description):
- if not re.match('^[a-zA-Z0-9_\- ]+$', str(group_name)):
- # Some validation to ensure that values match API spec.
- # - Alphanumeric characters, spaces, dashes, and underscores.
- # TODO(Daviey): LP: #813685 extend beyond group_name checking, and
- # probably create a param validator that can be used elsewhere.
- err = _("Value (%s) for parameter GroupName is invalid."
- " Content limited to Alphanumeric characters, "
- "spaces, dashes, and underscores.") % group_name
- # err not that of master ec2 implementation, as they fail to raise.
- raise exception.InvalidParameterValue(err=err)
-
- if len(str(group_name)) > 255:
+ if isinstance(group_name, unicode):
+ group_name = group_name.encode('utf-8')
+ # TODO(Daviey): LP: #813685 extend beyond group_name checking, and
+ # probably create a param validator that can be used elsewhere.
+ if FLAGS.ec2_strict_validation:
+ # EC2 specification gives constraints for name and description:
+ # Accepts alphanumeric characters, spaces, dashes, and underscores
+ err = _("Value (%(value)s) for parameter %(param)s is invalid."
+ " Content limited to Alphanumeric characters,"
+ " spaces, dashes, and underscores.")
+ if not re.match('^[a-zA-Z0-9_\- ]+$', group_name):
+ raise exception.InvalidParameterValue(
+ err=err % {"value": group_name,
+ "param": "GroupName"})
+ if not re.match('^[a-zA-Z0-9_\- ]+$', group_description):
+ raise exception.InvalidParameterValue(
+ err=err % {"value": group_description,
+ "param": "GroupDescription"})
+ else:
+ # Amazon accepts more symbols.
+ # So, allow POSIX [:print:] characters.
+ if not re.match(r'^[\x20-\x7E]+$', group_name):
+ err = _("Value (%(value)s) for parameter %(param)s is invalid."
+ " Content is limited to characters"
+ " from the [:print:] class.")
+ raise exception.InvalidParameterValue(
+ err=err % {"value": group_name,
+ "param": "GroupName"})
+
+ if len(group_name) > 255:
err = _("Value (%s) for parameter GroupName is invalid."
" Length exceeds maximum of 255.") % group_name
raise exception.InvalidParameterValue(err=err)
diff --git a/nova/tests/test_api.py b/nova/tests/test_api.py
index b0367dd8f..1970a672d 100644
--- a/nova/tests/test_api.py
+++ b/nova/tests/test_api.py
@@ -35,10 +35,14 @@ from nova import block_device
from nova.compute import api as compute_api
from nova import context
from nova import exception
+from nova import flags
from nova import test
from nova import utils
+FLAGS = flags.FLAGS
+
+
class FakeHttplibSocket(object):
"""a fake socket implementation for httplib.HTTPResponse, trivial"""
def __init__(self, response_string):
@@ -345,19 +349,37 @@ class ApiEc2TestCase(test.TestCase):
def test_group_name_valid_chars_security_group(self):
""" Test that we sanely handle invalid security group names.
- API Spec states we should only accept alphanumeric characters,
- spaces, dashes, and underscores. """
- self.expect_http()
- self.mox.ReplayAll()
-
- # Test block group_name of non alphanumeric characters, spaces,
- # dashes, and underscores.
- security_group_name = "aa #^% -=99"
-
- self.assertRaises(boto_exc.EC2ResponseError,
- self.ec2.create_security_group,
- security_group_name,
- 'test group')
+ EC2 API Spec states we should only accept alphanumeric characters,
+ spaces, dashes, and underscores. Amazon implementation
+ accepts more characters - so, [:print:] is ok. """
+
+ bad_strict_ec2 = "aa \t\x01\x02\x7f"
+ bad_amazon_ec2 = "aa #^% -=99"
+ test_raise = [
+ (True, bad_amazon_ec2, "test desc"),
+ (True, "test name", bad_amazon_ec2),
+ (False, bad_strict_ec2, "test desc"),
+ ]
+ for test in test_raise:
+ self.expect_http()
+ self.mox.ReplayAll()
+ FLAGS.ec2_strict_validation = test[0]
+ self.assertRaises(boto_exc.EC2ResponseError,
+ self.ec2.create_security_group,
+ test[1],
+ test[2])
+ test_accept = [
+ (False, bad_amazon_ec2, "test desc"),
+ (False, "test name", bad_amazon_ec2),
+ ]
+ for test in test_accept:
+ self.expect_http()
+ self.mox.ReplayAll()
+ FLAGS.ec2_strict_validation = test[0]
+ self.ec2.create_security_group(test[1], test[2])
+ self.expect_http()
+ self.mox.ReplayAll()
+ self.ec2.delete_security_group(test[1])
def test_group_name_valid_length_security_group(self):
"""Test that we sanely handle invalid security group names.