Templates of an extremely large size can eat up tons of CPU time,
memory and storage. By refusing to parse any template over a certain
size, we can prevent users from abusing the service.
Fixes bug #
1214234
Change-Id: I2f731c8e2fc9e1f497199e310de81fa48c9582af
# Keystone role for heat template-defined users (string value)
#heat_stack_user_role=heat_stack_user
+# Maximum raw byte size of any template. (integer value)
+#max_template_size=524288
+
#
# Options defined in heat.common.crypt
help='Instance connection to cfn/cw API validate certs if ssl'),
cfg.StrOpt('heat_stack_user_role',
default="heat_stack_user",
- help='Keystone role for heat template-defined users')]
+ help='Keystone role for heat template-defined users'),
+ cfg.IntOpt('max_template_size',
+ default=524288,
+ help='Maximum raw byte size of any template.')]
db_opts = [
cfg.StrOpt('sql_connection',
def __init__(self, exception):
self.exc = exception
self.tb = sys.exc_info()[2]
+
+
+class TemplateTooBig(OpenstackException):
+ message = _('Template exceeds maximum allowed size.')
import yaml
import json
+from oslo.config import cfg
+
+from heat.common import exception
+
+cfg.CONF.import_opt('max_template_size', 'heat.common.config')
+
HEAT_VERSIONS = (u'2012-12-12',)
CFN_VERSIONS = (u'2010-09-09',)
This includes determination of whether the string is using the
JSON or YAML format.
'''
+ if len(tmpl_str) > cfg.CONF.max_template_size:
+ raise exception.TemplateTooBig()
if tmpl_str.startswith('{'):
tpl = json.loads(tmpl_str)
else:
from testtools import skipIf
import os
+import yaml
from heat.engine import clients
+from heat.common import config
+from heat.common import exception
from heat.common import template_format
from heat.tests.common import HeatTestCase
from heat.tests import utils
tpl2 = template_format.parse(yaml2)
self.assertEqual(tpl1, tpl2)
+ def test_long_yaml(self):
+ template = {'HeatTemplateVersion': '2012-12-12'}
+ template['Resources'] = ['a'] * (config.cfg.CONF.max_template_size / 3)
+ limit = config.cfg.CONF.max_template_size
+ long_yaml = yaml.safe_dump(template)
+ self.assertTrue(len(long_yaml) > limit)
+ self.assertRaises(exception.TemplateTooBig, template_format.parse,
+ long_yaml)
+
class YamlEnvironmentTest(HeatTestCase):