Merge "Add common constraint to validate JSON string"
This commit is contained in:
commit
3a4582ca59
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
import croniter
|
import croniter
|
||||||
import eventlet
|
import eventlet
|
||||||
|
import json
|
||||||
import netaddr
|
import netaddr
|
||||||
import zoneinfo
|
import zoneinfo
|
||||||
|
|
||||||
@ -188,6 +189,19 @@ class ExpirationConstraint(constraints.BaseCustomConstraint):
|
|||||||
raise ValueError(_('Expiration time is out of date.'))
|
raise ValueError(_('Expiration time is out of date.'))
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self._error_message = (_(
|
self._error_message = (_(
|
||||||
'Expiration {0} is invalid: {1}').format(value,
|
'Expiration {0} is invalid: {1}').format(value, str(ex)))
|
||||||
str(ex)))
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class JsonStringConstraint(constraints.BaseCustomConstraint):
|
||||||
|
|
||||||
|
def validate(self, value, context):
|
||||||
|
if not value:
|
||||||
|
return True
|
||||||
|
try:
|
||||||
|
json.loads(value)
|
||||||
|
return True
|
||||||
|
except json.decoder.JSONDecodeError as ex:
|
||||||
|
self._error_message = (_(
|
||||||
|
'JSON string {0} is invalid: {1}').format(value, str(ex)))
|
||||||
return False
|
return False
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from heat.common.i18n import _
|
from heat.common.i18n import _
|
||||||
|
from heat.engine import constraints
|
||||||
from heat.engine import properties
|
from heat.engine import properties
|
||||||
from heat.engine import resource
|
from heat.engine import resource
|
||||||
from heat.engine import support
|
from heat.engine import support
|
||||||
@ -50,7 +51,8 @@ class AvailabilityZoneProfile(resource.Resource):
|
|||||||
properties.Schema.STRING,
|
properties.Schema.STRING,
|
||||||
_('JSON string containing the availability zone metadata.'),
|
_('JSON string containing the availability zone metadata.'),
|
||||||
update_allowed=True,
|
update_allowed=True,
|
||||||
required=True
|
required=True,
|
||||||
|
constraints=[constraints.CustomConstraint('json_string')]
|
||||||
),
|
),
|
||||||
PROVIDER_NAME: properties.Schema(
|
PROVIDER_NAME: properties.Schema(
|
||||||
properties.Schema.STRING,
|
properties.Schema.STRING,
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from heat.common.i18n import _
|
from heat.common.i18n import _
|
||||||
|
from heat.engine import constraints
|
||||||
from heat.engine import properties
|
from heat.engine import properties
|
||||||
from heat.engine import resource
|
from heat.engine import resource
|
||||||
from heat.engine import support
|
from heat.engine import support
|
||||||
@ -44,7 +45,8 @@ class FlavorProfile(resource.Resource):
|
|||||||
properties.Schema.STRING,
|
properties.Schema.STRING,
|
||||||
_('JSON string containing the flavor metadata.'),
|
_('JSON string containing the flavor metadata.'),
|
||||||
update_allowed=True,
|
update_allowed=True,
|
||||||
required=True
|
required=True,
|
||||||
|
constraints=[constraints.CustomConstraint('json_string')]
|
||||||
),
|
),
|
||||||
PROVIDER_NAME: properties.Schema(
|
PROVIDER_NAME: properties.Schema(
|
||||||
properties.Schema.STRING,
|
properties.Schema.STRING,
|
||||||
|
@ -445,3 +445,30 @@ class ExpirationConstraintTest(common.HeatTestCase):
|
|||||||
|
|
||||||
def test_validation_none(self):
|
def test_validation_none(self):
|
||||||
self.assertTrue(self.constraint.validate(None, self.ctx))
|
self.assertTrue(self.constraint.validate(None, self.ctx))
|
||||||
|
|
||||||
|
|
||||||
|
class JsonStringConstraintTest(common.HeatTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(JsonStringConstraintTest, self).setUp()
|
||||||
|
self.ctx = utils.dummy_context()
|
||||||
|
self.constraint = cc.JsonStringConstraint()
|
||||||
|
|
||||||
|
def test_validate_json(self):
|
||||||
|
data = '{"key": "value"}'
|
||||||
|
self.assertTrue(self.constraint.validate(data, None))
|
||||||
|
|
||||||
|
def test_validation_error(self):
|
||||||
|
data = '{\'key\': \'value\'}'
|
||||||
|
expected = (
|
||||||
|
"JSON string {0} is invalid: Expecting property name "
|
||||||
|
"enclosed in double quotes: line 1 column 2 (char 1)".format(data))
|
||||||
|
|
||||||
|
self.assertFalse(self.constraint.validate(data, self.ctx))
|
||||||
|
self.assertEqual(
|
||||||
|
expected,
|
||||||
|
str(self.constraint._error_message)
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_validation_none(self):
|
||||||
|
self.assertTrue(self.constraint.validate(None, self.ctx))
|
||||||
|
@ -108,6 +108,7 @@ heat.constraints =
|
|||||||
ip_or_cidr = heat.engine.constraint.common_constraints:IPCIDRConstraint
|
ip_or_cidr = heat.engine.constraint.common_constraints:IPCIDRConstraint
|
||||||
test_constr = heat.engine.constraint.common_constraints:TestConstraintDelay
|
test_constr = heat.engine.constraint.common_constraints:TestConstraintDelay
|
||||||
timezone = heat.engine.constraint.common_constraints:TimezoneConstraint
|
timezone = heat.engine.constraint.common_constraints:TimezoneConstraint
|
||||||
|
json_string = heat.engine.constraint.common_constraints:JsonStringConstraint
|
||||||
# service constraints
|
# service constraints
|
||||||
barbican.container = heat.engine.clients.os.barbican:ContainerConstraint
|
barbican.container = heat.engine.clients.os.barbican:ContainerConstraint
|
||||||
barbican.secret = heat.engine.clients.os.barbican:SecretConstraint
|
barbican.secret = heat.engine.clients.os.barbican:SecretConstraint
|
||||||
|
Loading…
Reference in New Issue
Block a user