Limit maximum size of all templates
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
This commit is contained in:
parent
1623b03517
commit
9fe8cbacd2
@ -70,6 +70,9 @@
|
||||
# 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
|
||||
|
@ -81,7 +81,10 @@ service_opts = [
|
||||
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',
|
||||
|
@ -297,3 +297,7 @@ class HTTPExceptionDisguise(Exception):
|
||||
def __init__(self, exception):
|
||||
self.exc = exception
|
||||
self.tb = sys.exc_info()[2]
|
||||
|
||||
|
||||
class TemplateTooBig(OpenstackException):
|
||||
message = _('Template exceeds maximum allowed size.')
|
||||
|
@ -17,6 +17,12 @@ import re
|
||||
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',)
|
||||
|
||||
@ -43,6 +49,8 @@ def parse(tmpl_str, add_template_sections=True):
|
||||
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:
|
||||
|
@ -14,8 +14,11 @@
|
||||
|
||||
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
|
||||
@ -89,6 +92,15 @@ Outputs: {}
|
||||
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):
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user