def is_template(file_content): try: if isinstance(file_content, six.binary_type): file_content = file_content.decode('utf-8') template_format.parse(file_content) except (ValueError, TypeError): return False return True
def get_template_contents(template_file=None, template_url=None, template_object=None, object_request=None): # Transform a bare file path to a file:// URL. if template_file: template_url = normalise_file_path_to_url(template_file) if template_url: tpl = urlutils.urlopen(template_url).read() elif template_object: template_url = template_object tpl = object_request and object_request('GET', template_object) else: raise exc.CommandError('Need to specify exactly one of ' '--template-file, --template-url ' 'or --template-object') if not tpl: raise exc.CommandError('Could not fetch template from %s' % template_url) try: template = template_format.parse(tpl) except ValueError as e: raise exc.CommandError( 'Error parsing template %s %s' % (template_url, e)) files = {} tmpl_base_url = base_url_for_url(template_url) resolve_template_get_files(template, files, tmpl_base_url) return files, template
def test_launch_stack(self): template = self.stack_templates.first() stack = self.stacks.first() api.heat.template_validate(IsA(http.HttpRequest), files={}, template=hc_format.parse(template.data)) \ .AndReturn(json.loads(template.validate)) api.heat.stack_create(IsA(http.HttpRequest), stack_name=stack.stack_name, timeout_mins=60, disable_rollback=True, template=None, parameters=IsA(dict), password='******', files=None) dashboard_api.neutron.network_list_for_tenant(IsA(http.HttpRequest), self.tenant.id) \ .AndReturn(self.networks.list()) dashboard_api.neutron.network_list_for_tenant(IsA(http.HttpRequest), self.tenant.id) \ .AndReturn(self.networks.list()) self.mox.ReplayAll() url = reverse('horizon:project:stacks:select_template') res = self.client.get(url) self.assertTemplateUsed(res, 'project/stacks/select_template.html') form_data = { 'template_source': 'raw', 'template_data': template.data, 'referenced_files': {}, 'method': forms.TemplateForm.__name__ } res = self.client.post(url, form_data) self.assertTemplateUsed(res, 'project/stacks/create.html') url = reverse('horizon:project:stacks:launch') form_data = { 'template_source': 'raw', 'template_data': template.data, 'password': '******', 'parameters': template.validate, 'stack_name': stack.stack_name, "timeout_mins": 60, "disable_rollback": True, "__param_DBUsername": "******", "__param_LinuxDistribution": "F17", "__param_InstanceType": "m1.small", "__param_KeyName": "test", "__param_DBPassword": "******", "__param_DBRootPassword": "******", "__param_DBName": "wordpress", "__param_Network": self.networks.list()[0]['id'], 'method': forms.CreateStackForm.__name__ } res = self.client.post(url, form_data) self.assertRedirectsNoFollow(res, INDEX_URL)
def test_launch_stack(self): template = self.stack_templates.first() stack = self.stacks.first() self.mock_template_validate.return_value = \ json.loads(template.validate) self.mock_stack_create.reutrn_value = None self.mock_network_list_for_tenant.side_effect = \ [self.networks.list(), self.networks.list()] url = reverse('horizon:project:stacks:select_template') res = self.client.get(url) self.assertTemplateUsed(res, 'project/stacks/select_template.html') form_data = { 'template_source': 'raw', 'template_data': template.data, 'referenced_files': {}, 'method': forms.TemplateForm.__name__ } res = self.client.post(url, form_data) self.assertTemplateUsed(res, 'project/stacks/create.html') url = reverse('horizon:project:stacks:launch') form_data = { 'template_source': 'raw', 'template_data': template.data, 'password': '******', 'parameters': template.validate, 'stack_name': stack.stack_name, "timeout_mins": 60, "disable_rollback": True, "__param_DBUsername": "******", "__param_LinuxDistribution": "F17", "__param_InstanceType": "m1.small", "__param_KeyName": "test", "__param_DBPassword": "******", "__param_DBRootPassword": "******", "__param_DBName": "wordpress", "__param_Network": self.networks.list()[0]['id'], 'method': forms.CreateStackForm.__name__ } res = self.client.post(url, form_data) self.assertRedirectsNoFollow(res, INDEX_URL) self.mock_template_validate.assert_called_once_with( test.IsHttpRequest(), files={}, template=hc_format.parse(template.data)) self.mock_stack_create.assert_called_once_with( test.IsHttpRequest(), stack_name=stack.stack_name, timeout_mins=60, disable_rollback=True, template=None, parameters=test.IsA(dict), password='******', files=None) self.mock_network_list_for_tenant.assert_has_calls([ mock.call(test.IsHttpRequest(), self.tenant.id), mock.call(test.IsHttpRequest(), self.tenant.id) ])
def test_launch_stack_with_hidden_parameters(self): template = { 'data': ('heat_template_version: 2013-05-23\n' 'parameters:\n' ' public_string:\n' ' type: string\n' ' secret_string:\n' ' type: string\n' ' hidden: true\n'), 'validate': { 'Description': 'No description', 'Parameters': { 'public_string': { 'Label': 'public_string', 'Description': '', 'Type': 'String', 'NoEcho': 'false' }, 'secret_string': { 'Label': 'secret_string', 'Description': '', 'Type': 'String', 'NoEcho': 'true' } } } } api.heat.template_validate(IsA(http.HttpRequest), files={}, template=hc_format.parse(template['data'])) \ .AndReturn(template['validate']) self.mox.ReplayAll() url = reverse('horizon:project:stacks:select_template') res = self.client.get(url) self.assertTemplateUsed(res, 'project/stacks/select_template.html') form_data = { 'template_source': 'raw', 'template_data': template['data'], 'method': forms.TemplateForm.__name__ } res = self.client.post(url, form_data) self.assertTemplateUsed(res, 'project/stacks/create.html') # ensure the fields were rendered correctly self.assertContains(res, '<input class="form-control" ' 'id="id___param_public_string" ' 'name="__param_public_string" ' 'type="text" />', html=True) self.assertContains(res, '<input class="form-control" ' 'id="id___param_secret_string" ' 'name="__param_secret_string" ' 'type="password" />', html=True)
def test_launch_stack(self): template = self.stack_templates.first() stack = self.stacks.first() api.heat.template_validate(IsA(http.HttpRequest), files={}, template=hc_format.parse(template.data)) \ .AndReturn(json.loads(template.validate)) api.heat.stack_create(IsA(http.HttpRequest), stack_name=stack.stack_name, timeout_mins=60, disable_rollback=True, template=None, parameters=IsA(dict), password='******', files=None) api.neutron.network_list_for_tenant(IsA(http.HttpRequest), self.tenant.id) \ .AndReturn(self.networks.list()) api.neutron.network_list_for_tenant(IsA(http.HttpRequest), self.tenant.id) \ .AndReturn(self.networks.list()) self.mox.ReplayAll() url = reverse('horizon:project:stacks:select_template') res = self.client.get(url) self.assertTemplateUsed(res, 'project/stacks/select_template.html') form_data = {'template_source': 'raw', 'template_data': template.data, 'method': forms.TemplateForm.__name__} res = self.client.post(url, form_data) self.assertTemplateUsed(res, 'project/stacks/create.html') url = reverse('horizon:project:stacks:launch') form_data = {'template_source': 'raw', 'template_data': template.data, 'password': '******', 'parameters': template.validate, 'stack_name': stack.stack_name, "timeout_mins": 60, "disable_rollback": True, "__param_DBUsername": "******", "__param_LinuxDistribution": "F17", "__param_InstanceType": "m1.small", "__param_KeyName": "test", "__param_DBPassword": "******", "__param_DBRootPassword": "******", "__param_DBName": "wordpress", "__param_Network": self.networks.list()[0]['id'], 'method': forms.CreateStackForm.__name__} res = self.client.post(url, form_data) self.assertRedirectsNoFollow(res, INDEX_URL)
def test_launch_stack_with_hidden_parameters(self): template = { 'data': ('heat_template_version: 2013-05-23\n' 'parameters:\n' ' public_string:\n' ' type: string\n' ' secret_string:\n' ' type: string\n' ' hidden: true\n'), 'validate': { 'Description': 'No description', 'Parameters': { 'public_string': { 'Label': 'public_string', 'Description': '', 'Type': 'String', 'NoEcho': 'false' }, 'secret_string': { 'Label': 'secret_string', 'Description': '', 'Type': 'String', 'NoEcho': 'true' } } } } api.heat.template_validate(IsA(http.HttpRequest), files={}, template=hc_format.parse(template['data'])) \ .AndReturn(template['validate']) self.mox.ReplayAll() url = reverse('horizon:project:stacks:select_template') res = self.client.get(url) self.assertTemplateUsed(res, 'project/stacks/select_template.html') form_data = {'template_source': 'raw', 'template_data': template['data'], 'method': forms.TemplateForm.__name__} res = self.client.post(url, form_data) self.assertTemplateUsed(res, 'project/stacks/create.html') # ensure the fields were rendered correctly self.assertContains(res, '<input class="form-control" ' 'id="id___param_public_string" ' 'name="__param_public_string" ' 'type="text" />', html=True) self.assertContains(res, '<input class="form-control" ' 'id="id___param_secret_string" ' 'name="__param_secret_string" ' 'type="password" />', html=True)
def get_template_contents(template_file=None, template_url=None, template_object=None, object_request=None, files=None, existing=False, fetch_child=True): is_object = False # Transform a bare file path to a file:// URL. if template_file: template_url = utils.normalise_file_path_to_url(template_file) if template_url: tpl = request.urlopen(template_url).read() elif template_object: is_object = True template_url = template_object tpl = object_request and object_request('GET', template_object) elif existing: return {}, None else: raise exc.CommandError( _('Need to specify exactly one of ' '[%(arg1)s, %(arg2)s or %(arg3)s]' ' or %(arg4)s') % { 'arg1': '--template-file', 'arg2': '--template-url', 'arg3': '--template-object', 'arg4': '--existing' }) if not tpl: raise exc.CommandError( _('Could not fetch template from %s') % template_url) try: if isinstance(tpl, six.binary_type): tpl = tpl.decode('utf-8') template = template_format.parse(tpl) except ValueError as e: raise exc.CommandError( _('Error parsing template %(url)s %(error)s') % { 'url': template_url, 'error': e }) if files is None: files = {} if fetch_child: tmpl_base_url = utils.base_url_for_url(template_url) resolve_template_get_files(template, files, tmpl_base_url, is_object, object_request) return files, template
def test_preview_stack(self): template = self.stack_templates.first() stack = self.stacks.first() api.heat.template_validate(IsA(http.HttpRequest), files={}, template=hc_format.parse(template.data)).AndReturn( json.loads(template.validate) ) api.heat.stack_preview( IsA(http.HttpRequest), stack_name=stack.stack_name, timeout_mins=60, disable_rollback=True, template=None, parameters=IsA(dict), files=None, ).AndReturn(stack) self.mox.ReplayAll() url = reverse("horizon:project:stacks:preview_template") res = self.client.get(url) self.assertTemplateUsed(res, "project/stacks/preview_template.html") form_data = { "template_source": "raw", "template_data": template.data, "method": forms.PreviewTemplateForm.__name__, } res = self.client.post(url, form_data) self.assertTemplateUsed(res, "project/stacks/preview.html") url = reverse("horizon:project:stacks:preview") form_data = { "template_source": "raw", "template_data": template.data, "parameters": template.validate, "stack_name": stack.stack_name, "timeout_mins": 60, "disable_rollback": True, "__param_DBUsername": "******", "__param_LinuxDistribution": "F17", "__param_InstanceType": "m1.small", "__param_KeyName": "test", "__param_DBPassword": "******", "__param_DBRootPassword": "******", "__param_DBName": "wordpress", "method": forms.PreviewStackForm.__name__, } res = self.client.post(url, form_data) self.assertTemplateUsed(res, "project/stacks/preview_details.html") self.assertEqual(res.context["stack_preview"]["stack_name"], stack.stack_name)
def test_preview_stack(self): template = self.stack_templates.first() stack = self.stacks.first() api.heat.template_validate(IsA(http.HttpRequest), files={}, template=hc_format.parse(template.data)) \ .AndReturn(json.loads(template.validate)) api.heat.stack_preview(IsA(http.HttpRequest), stack_name=stack.stack_name, timeout_mins=60, disable_rollback=True, template=None, parameters=IsA(dict), files=None).AndReturn(stack) self.mox.ReplayAll() url = reverse('horizon:project:stacks:preview_template') res = self.client.get(url) self.assertTemplateUsed(res, 'project/stacks/preview_template.html') form_data = { 'template_source': 'raw', 'template_data': template.data, 'method': forms.PreviewTemplateForm.__name__ } res = self.client.post(url, form_data) self.assertTemplateUsed(res, 'project/stacks/preview.html') url = reverse('horizon:project:stacks:preview') form_data = { 'template_source': 'raw', 'template_data': template.data, 'parameters': template.validate, 'stack_name': stack.stack_name, "timeout_mins": 60, "disable_rollback": True, "__param_DBUsername": "******", "__param_LinuxDistribution": "F17", "__param_InstanceType": "m1.small", "__param_KeyName": "test", "__param_DBPassword": "******", "__param_DBRootPassword": "******", "__param_DBName": "wordpress", 'method': forms.PreviewStackForm.__name__ } res = self.client.post(url, form_data) self.assertTemplateUsed(res, 'project/stacks/preview_details.html') self.assertEqual(res.context['stack_preview']['stack_name'], stack.stack_name)
def get_template_files(template_data=None, template_url=None): if template_data: tpl = template_data elif template_url: with contextlib.closing(request.urlopen(template_url)) as u: tpl = u.read() else: return {}, None if not tpl: return {}, None if isinstance(tpl, six.binary_type): tpl = tpl.decode('utf-8') template = template_format.parse(tpl) files = {} _get_file_contents(template, files) return files, template
def get_template_contents(template_file=None, template_url=None, template_object=None, object_request=None, files=None, existing=False): is_object = False # Transform a bare file path to a file:// URL. if template_file: template_url = utils.normalise_file_path_to_url(template_file) if template_url: tpl = request.urlopen(template_url).read() elif template_object: is_object = True template_url = template_object tpl = object_request and object_request('GET', template_object) elif existing: return {}, None else: raise exc.CommandError(_('Need to specify exactly one of ' '[%(arg1)s, %(arg2)s or %(arg3)s]' ' or %(arg4)s') % { 'arg1': '--template-file', 'arg2': '--template-url', 'arg3': '--template-object', 'arg4': '--existing'}) if not tpl: raise exc.CommandError(_('Could not fetch template from %s') % template_url) try: if isinstance(tpl, six.binary_type): tpl = tpl.decode('utf-8') template = template_format.parse(tpl) except ValueError as e: raise exc.CommandError(_('Error parsing template %(url)s %(error)s') % {'url': template_url, 'error': e}) tmpl_base_url = utils.base_url_for_url(template_url) if files is None: files = {} resolve_template_get_files(template, files, tmpl_base_url, is_object, object_request) return files, template
def test_preview_stack(self): template = self.stack_templates.first() stack = self.stacks.first() self.mock_template_validate.return_value = \ json.loads(template.validate) self.mock_stack_preview.return_value = stack url = reverse('horizon:project:stacks:preview_template') res = self.client.get(url) self.assertTemplateUsed(res, 'project/stacks/preview_template.html') form_data = { 'template_source': 'raw', 'template_data': template.data, 'method': forms.PreviewTemplateForm.__name__ } res = self.client.post(url, form_data) self.assertTemplateUsed(res, 'project/stacks/preview.html') url = reverse('horizon:project:stacks:preview') form_data = { 'template_source': 'raw', 'template_data': template.data, 'parameters': template.validate, 'stack_name': stack.stack_name, "timeout_mins": 60, "disable_rollback": True, "__param_DBUsername": "******", "__param_LinuxDistribution": "F17", "__param_InstanceType": "m1.small", "__param_KeyName": "test", "__param_DBPassword": "******", "__param_DBRootPassword": "******", "__param_DBName": "wordpress", 'method': forms.PreviewStackForm.__name__ } res = self.client.post(url, form_data) self.assertTemplateUsed(res, 'project/stacks/preview_details.html') self.assertEqual(res.context['stack_preview']['stack_name'], stack.stack_name) self.mock_template_validate.assert_called_once_with( test.IsHttpRequest(), files={}, template=hc_format.parse(template.data))
def test_launch_stack_with_parameter_group(self): template = { "data": ( "heat_template_version: 2013-05-23\n" "parameters:\n" " last_param:\n" " type: string\n" " first_param:\n" " type: string\n" " middle_param:\n" " type: string\n" "parameter_groups:\n" "- parameters:\n" " - first_param\n" " - middle_param\n" " - last_param\n" ), "validate": { "Description": "No description", "Parameters": { "last_param": {"Label": "last_param", "Description": "", "Type": "String", "NoEcho": "false"}, "first_param": {"Label": "first_param", "Description": "", "Type": "String", "NoEcho": "false"}, "middle_param": {"Label": "middle_param", "Description": "", "Type": "String", "NoEcho": "true"}, }, "ParameterGroups": [{"parameters": ["first_param", "middle_param", "last_param"]}], }, } api.heat.template_validate( IsA(http.HttpRequest), files={}, template=hc_format.parse(template["data"]) ).AndReturn(template["validate"]) self.mox.ReplayAll() url = reverse("horizon:project:stacks:select_template") res = self.client.get(url) self.assertTemplateUsed(res, "project/stacks/select_template.html") form_data = {"template_source": "raw", "template_data": template["data"], "method": forms.TemplateForm.__name__} res = self.client.post(url, form_data) self.assertTemplateUsed(res, "project/stacks/create.html") # ensure the fields were rendered in the correct order regex = re.compile("^.*>first_param<.*>middle_param<.*>last_param<.*$", flags=re.DOTALL) self.assertRegexpMatches(res.content.decode("utf-8"), regex)
def get_template_contents(template_file=None, template_url=None, template_object=None, object_request=None, files=None): # Transform a bare file path to a file:// URL. if template_file: template_url = normalise_file_path_to_url(template_file) if template_url: tpl = request.urlopen(template_url).read() elif template_object: template_url = template_object tpl = object_request and object_request('GET', template_object) else: raise exc.CommandError('Need to specify exactly one of ' '--template-file, --template-url ' 'or --template-object') if not tpl: raise exc.CommandError('Could not fetch template from %s' % template_url) try: if isinstance(tpl, six.binary_type): tpl = tpl.decode('utf-8') template = template_format.parse(tpl) except ValueError as e: raise exc.CommandError('Error parsing template %s %s' % (template_url, e)) tmpl_base_url = base_url_for_url(template_url) if files is None: files = {} resolve_template_get_files(template, files, tmpl_base_url) resolve_template_type(template, files, tmpl_base_url) return files, template
def test_launch_stack_parameter_types(self): template = { 'data': ('heat_template_version: 2013-05-23\n' 'parameters:\n' ' param1:\n' ' type: string\n' ' param2:\n' ' type: number\n' ' param3:\n' ' type: json\n' ' param4:\n' ' type: comma_delimited_list\n' ' param5:\n' ' type: boolean\n'), 'validate': { "Description": "No description", "Parameters": { "param1": { "Type": "String", "NoEcho": "false", "Description": "", "Label": "param1" }, "param2": { "Type": "Number", "NoEcho": "false", "Description": "", "Label": "param2" }, "param3": { "Type": "Json", "NoEcho": "false", "Description": "", "Label": "param3" }, "param4": { "Type": "CommaDelimitedList", "NoEcho": "false", "Description": "", "Label": "param4" }, "param5": { "Type": "Boolean", "NoEcho": "false", "Description": "", "Label": "param5" } } } } stack = self.stacks.first() api.heat.template_validate(IsA(http.HttpRequest), files={}, template=hc_format.parse(template['data'])) \ .AndReturn(template['validate']) api.heat.stack_create(IsA(http.HttpRequest), stack_name=stack.stack_name, timeout_mins=60, disable_rollback=True, template=hc_format.parse(template['data']), parameters={ 'param1': 'some string', 'param2': 42, 'param3': '{"key": "value"}', 'param4': 'a,b,c', 'param5': True }, password='******', files={}) self.mox.ReplayAll() url = reverse('horizon:project:stacks:select_template') res = self.client.get(url) self.assertTemplateUsed(res, 'project/stacks/select_template.html') form_data = { 'template_source': 'raw', 'template_data': template['data'], 'method': forms.TemplateForm.__name__ } res = self.client.post(url, form_data) self.assertTemplateUsed(res, 'project/stacks/create.html') # ensure the fields were rendered correctly if django.VERSION >= (1, 10): input_str = ('<input class="form-control" ' 'id="id___param_param{0}" ' 'name="__param_param{0}" type="{1}" required/>') else: input_str = ('<input class="form-control" ' 'id="id___param_param{0}" ' 'name="__param_param{0}" type="{1}"/>') self.assertContains(res, input_str.format(1, 'text'), html=True) self.assertContains(res, input_str.format(2, 'number'), html=True) self.assertContains(res, input_str.format(3, 'text'), html=True) self.assertContains(res, input_str.format(4, 'text'), html=True) self.assertContains( res, '<input id="id___param_param5" name="__param_param5" ' 'type="checkbox">', html=True) # post some sample data and make sure it validates url = reverse('horizon:project:stacks:launch') form_data = { 'template_source': 'raw', 'template_data': template['data'], 'password': '******', 'parameters': json.dumps(template['validate']), 'stack_name': stack.stack_name, "timeout_mins": 60, "disable_rollback": True, "__param_param1": "some string", "__param_param2": 42, "__param_param3": '{"key": "value"}', "__param_param4": "a,b,c", "__param_param5": True, 'method': forms.CreateStackForm.__name__ } res = self.client.post(url, form_data) self.assertRedirectsNoFollow(res, INDEX_URL)
def test_launch_stack_with_parameter_group(self): template = { 'data': ('heat_template_version: 2013-05-23\n' 'parameters:\n' ' last_param:\n' ' type: string\n' ' first_param:\n' ' type: string\n' ' middle_param:\n' ' type: string\n' 'parameter_groups:\n' '- parameters:\n' ' - first_param\n' ' - middle_param\n' ' - last_param\n'), 'validate': { 'Description': 'No description', 'Parameters': { 'last_param': { 'Label': 'last_param', 'Description': '', 'Type': 'String', 'NoEcho': 'false' }, 'first_param': { 'Label': 'first_param', 'Description': '', 'Type': 'String', 'NoEcho': 'false' }, 'middle_param': { 'Label': 'middle_param', 'Description': '', 'Type': 'String', 'NoEcho': 'true' } }, 'ParameterGroups': [{ 'parameters': ['first_param', 'middle_param', 'last_param'] }] } } api.heat.template_validate(IsA(http.HttpRequest), files={}, template=hc_format.parse(template['data'])) \ .AndReturn(template['validate']) self.mox.ReplayAll() url = reverse('horizon:project:stacks:select_template') res = self.client.get(url) self.assertTemplateUsed(res, 'project/stacks/select_template.html') form_data = { 'template_source': 'raw', 'template_data': template['data'], 'method': forms.TemplateForm.__name__ } res = self.client.post(url, form_data) self.assertTemplateUsed(res, 'project/stacks/create.html') # ensure the fields were rendered in the correct order regex = re.compile('^.*>first_param<.*>middle_param<.*>last_param<.*$', flags=re.DOTALL) self.assertRegexpMatches(res.content.decode('utf-8'), regex)
def test_launch_stack_parameter_types(self): template = { "data": ( "heat_template_version: 2013-05-23\n" "parameters:\n" " param1:\n" " type: string\n" " param2:\n" " type: number\n" " param3:\n" " type: json\n" " param4:\n" " type: comma_delimited_list\n" " param5:\n" " type: boolean\n" ), "validate": { "Description": "No description", "Parameters": { "param1": {"Type": "String", "NoEcho": "false", "Description": "", "Label": "param1"}, "param2": {"Type": "Number", "NoEcho": "false", "Description": "", "Label": "param2"}, "param3": {"Type": "Json", "NoEcho": "false", "Description": "", "Label": "param3"}, "param4": {"Type": "CommaDelimitedList", "NoEcho": "false", "Description": "", "Label": "param4"}, "param5": {"Type": "Boolean", "NoEcho": "false", "Description": "", "Label": "param5"}, }, }, } stack = self.stacks.first() api.heat.template_validate( IsA(http.HttpRequest), files={}, template=hc_format.parse(template["data"]) ).AndReturn(template["validate"]) api.heat.stack_create( IsA(http.HttpRequest), stack_name=stack.stack_name, timeout_mins=60, disable_rollback=True, template=hc_format.parse(template["data"]), parameters={ "param1": "some string", "param2": 42, "param3": '{"key": "value"}', "param4": "a,b,c", "param5": True, }, password="******", files={}, ) self.mox.ReplayAll() url = reverse("horizon:project:stacks:select_template") res = self.client.get(url) self.assertTemplateUsed(res, "project/stacks/select_template.html") form_data = {"template_source": "raw", "template_data": template["data"], "method": forms.TemplateForm.__name__} res = self.client.post(url, form_data) self.assertTemplateUsed(res, "project/stacks/create.html") # ensure the fields were rendered correctly if django.VERSION >= (1, 10): input_str = ( '<input class="form-control" ' 'id="id___param_param{0}" ' 'name="__param_param{0}" type="{1}" required/>' ) else: input_str = ( '<input class="form-control" ' 'id="id___param_param{0}" ' 'name="__param_param{0}" type="{1}"/>' ) self.assertContains(res, input_str.format(1, "text"), html=True) self.assertContains(res, input_str.format(2, "number"), html=True) self.assertContains(res, input_str.format(3, "text"), html=True) self.assertContains(res, input_str.format(4, "text"), html=True) self.assertContains(res, '<input id="id___param_param5" name="__param_param5" ' 'type="checkbox">', html=True) # post some sample data and make sure it validates url = reverse("horizon:project:stacks:launch") form_data = { "template_source": "raw", "template_data": template["data"], "password": "******", "parameters": json.dumps(template["validate"]), "stack_name": stack.stack_name, "timeout_mins": 60, "disable_rollback": True, "__param_param1": "some string", "__param_param2": 42, "__param_param3": '{"key": "value"}', "__param_param4": "a,b,c", "__param_param5": True, "method": forms.CreateStackForm.__name__, } res = self.client.post(url, form_data) self.assertRedirectsNoFollow(res, INDEX_URL)
def test_edit_stack_template(self): template = self.stack_templates.first() stack = self.stacks.first() # GET to template form api.heat.stack_get(IsA(http.HttpRequest), stack.id).AndReturn(stack) # POST template form, validation api.heat.template_validate(IsA(http.HttpRequest), files={}, template=hc_format.parse(template.data)) \ .AndReturn(json.loads(template.validate)) # GET to edit form api.heat.stack_get(IsA(http.HttpRequest), stack.id).AndReturn(stack) api.heat.template_get(IsA(http.HttpRequest), stack.id) \ .AndReturn(json.loads(template.validate)) # POST to edit form api.heat.stack_get(IsA(http.HttpRequest), stack.id).AndReturn(stack) fields = { 'stack_name': stack.stack_name, 'disable_rollback': True, 'timeout_mins': 61, 'password': '******', 'template': None, 'parameters': IsA(dict), 'files': None } api.heat.stack_update(IsA(http.HttpRequest), stack_id=stack.id, **fields) api.neutron.network_list_for_tenant(IsA(http.HttpRequest), self.tenant.id) \ .AndReturn(self.networks.list()) self.mox.ReplayAll() url = reverse('horizon:project:stacks:change_template', args=[stack.id]) res = self.client.get(url) self.assertTemplateUsed(res, 'project/stacks/change_template.html') form_data = {'template_source': 'raw', 'template_data': template.data, 'method': forms.ChangeTemplateForm.__name__} res = self.client.post(url, form_data) url = reverse('horizon:project:stacks:edit_stack', args=[stack.id, ]) form_data = {'template_source': 'raw', 'template_data': template.data, 'password': '******', 'parameters': template.validate, 'stack_name': stack.stack_name, 'stack_id': stack.id, "timeout_mins": 61, "disable_rollback": True, "__param_DBUsername": "******", "__param_LinuxDistribution": "F17", "__param_InstanceType": "m1.small", "__param_KeyName": "test", "__param_DBPassword": "******", "__param_DBRootPassword": "******", "__param_DBName": "wordpress", "__param_Network": self.networks.list()[0]['id'], 'method': forms.EditStackForm.__name__} res = self.client.post(url, form_data) self.assertRedirectsNoFollow(res, INDEX_URL)
def test_launch_stack_parameter_types(self): template = { 'data': ('heat_template_version: 2013-05-23\n' 'parameters:\n' ' param1:\n' ' type: string\n' ' param2:\n' ' type: number\n' ' param3:\n' ' type: json\n' ' param4:\n' ' type: comma_delimited_list\n' ' param5:\n' ' type: boolean\n'), 'validate': { "Description": "No description", "Parameters": { "param1": { "Type": "String", "NoEcho": "false", "Description": "", "Label": "param1" }, "param2": { "Type": "Number", "NoEcho": "false", "Description": "", "Label": "param2" }, "param3": { "Type": "Json", "NoEcho": "false", "Description": "", "Label": "param3" }, "param4": { "Type": "CommaDelimitedList", "NoEcho": "false", "Description": "", "Label": "param4" }, "param5": { "Type": "Boolean", "NoEcho": "false", "Description": "", "Label": "param5" } } } } stack = self.stacks.first() api.heat.template_validate(IsA(http.HttpRequest), files={}, template=hc_format.parse(template['data'])) \ .AndReturn(template['validate']) api.heat.stack_create(IsA(http.HttpRequest), stack_name=stack.stack_name, timeout_mins=60, disable_rollback=True, template=hc_format.parse(template['data']), parameters={'param1': 'some string', 'param2': 42, 'param3': '{"key": "value"}', 'param4': 'a,b,c', 'param5': True}, password='******', files={}) self.mox.ReplayAll() url = reverse('horizon:project:stacks:select_template') res = self.client.get(url) self.assertTemplateUsed(res, 'project/stacks/select_template.html') form_data = {'template_source': 'raw', 'template_data': template['data'], 'method': forms.TemplateForm.__name__} res = self.client.post(url, form_data) self.assertTemplateUsed(res, 'project/stacks/create.html') # ensure the fields were rendered correctly self.assertContains(res, '<input class="form-control" ' 'id="id___param_param1" ' 'name="__param_param1" ' 'type="text" />', html=True) self.assertContains(res, '<input class="form-control" ' 'id="id___param_param2" ' 'name="__param_param2" ' 'type="number" />', html=True) self.assertContains(res, '<input class="form-control" ' 'id="id___param_param3" ' 'name="__param_param3" ' 'type="text" />', html=True) self.assertContains(res, '<input class="form-control" ' 'id="id___param_param4" ' 'name="__param_param4" ' 'type="text" />', html=True) self.assertContains(res, '<input id="id___param_param5" ' 'name="__param_param5" ' 'type="checkbox" />', html=True) # post some sample data and make sure it validates url = reverse('horizon:project:stacks:launch') form_data = {'template_source': 'raw', 'template_data': template['data'], 'password': '******', 'parameters': json.dumps(template['validate']), 'stack_name': stack.stack_name, "timeout_mins": 60, "disable_rollback": True, "__param_param1": "some string", "__param_param2": 42, "__param_param3": '{"key": "value"}', "__param_param4": "a,b,c", "__param_param5": True, 'method': forms.CreateStackForm.__name__} res = self.client.post(url, form_data) self.assertRedirectsNoFollow(res, INDEX_URL)
def test_launch_stack_with_hidden_parameters(self): template = { 'data': ('heat_template_version: 2013-05-23\n' 'parameters:\n' ' public_string:\n' ' type: string\n' ' secret_string:\n' ' type: string\n' ' hidden: true\n'), 'validate': { 'Description': 'No description', 'Parameters': { 'public_string': { 'Label': 'public_string', 'Description': '', 'Type': 'String', 'NoEcho': 'false' }, 'secret_string': { 'Label': 'secret_string', 'Description': '', 'Type': 'String', 'NoEcho': 'true' } } } } self.mock_template_validate.return_value = template['validate'] url = reverse('horizon:project:stacks:select_template') res = self.client.get(url) self.assertTemplateUsed(res, 'project/stacks/select_template.html') form_data = { 'template_source': 'raw', 'template_data': template['data'], 'method': forms.TemplateForm.__name__ } res = self.client.post(url, form_data) self.assertTemplateUsed(res, 'project/stacks/create.html') # ensure the fields were rendered correctly if (1, 10) <= django.VERSION < (2, 1): pattern = ('<input class="form-control" ' 'id="id___param_public_string" ' 'name="__param_public_string" type="text" required/>') secret = ('<input class="form-control" ' 'id="id___param_secret_string" ' 'name="__param_secret_string" ' 'type="password" required>') else: pattern = ('<input class="form-control" ' 'id="id___param_public_string" ' 'name="__param_public_string" type="text" />') secret = ('<input class="form-control" ' 'id="id___param_secret_string" ' 'name="__param_secret_string" ' 'type="password" />') self.assertContains(res, pattern, html=True) self.assertContains(res, secret, html=True) self.mock_template_validate.assert_called_once_with( test.IsHttpRequest(), files={}, template=hc_format.parse(template['data']))
def test_launch_stack_with_hidden_parameters(self): template = { "data": ( "heat_template_version: 2013-05-23\n" "parameters:\n" " public_string:\n" " type: string\n" " secret_string:\n" " type: string\n" " hidden: true\n" ), "validate": { "Description": "No description", "Parameters": { "public_string": {"Label": "public_string", "Description": "", "Type": "String", "NoEcho": "false"}, "secret_string": {"Label": "secret_string", "Description": "", "Type": "String", "NoEcho": "true"}, }, }, } api.heat.template_validate( IsA(http.HttpRequest), files={}, template=hc_format.parse(template["data"]) ).AndReturn(template["validate"]) self.mox.ReplayAll() url = reverse("horizon:project:stacks:select_template") res = self.client.get(url) self.assertTemplateUsed(res, "project/stacks/select_template.html") form_data = {"template_source": "raw", "template_data": template["data"], "method": forms.TemplateForm.__name__} res = self.client.post(url, form_data) self.assertTemplateUsed(res, "project/stacks/create.html") # ensure the fields were rendered correctly if django.VERSION >= (1, 10): pattern = ( '<input class="form-control" ' 'id="id___param_public_string" ' 'name="__param_public_string" type="text" required/>' ) secret = ( '<input class="form-control" ' 'id="id___param_secret_string" ' 'name="__param_secret_string" ' 'type="password" required>' ) else: pattern = ( '<input class="form-control" ' 'id="id___param_public_string" ' 'name="__param_public_string" type="text" />' ) secret = ( '<input class="form-control" ' 'id="id___param_secret_string" ' 'name="__param_secret_string" ' 'type="password" />' ) self.assertContains(res, pattern, html=True) self.assertContains(res, secret, html=True)
def test_edit_stack_template(self): template = self.stack_templates.first() stack = self.stacks.first() # GET to template form api.heat.stack_get(IsA(http.HttpRequest), stack.id).AndReturn(stack) # POST template form, validation api.heat.template_validate(IsA(http.HttpRequest), files={}, template=hc_format.parse(template.data)) \ .AndReturn(json.loads(template.validate)) # GET to edit form api.heat.stack_get(IsA(http.HttpRequest), stack.id).AndReturn(stack) api.heat.template_get(IsA(http.HttpRequest), stack.id) \ .AndReturn(json.loads(template.validate)) # POST to edit form api.heat.stack_get(IsA(http.HttpRequest), stack.id).AndReturn(stack) fields = { 'stack_name': stack.stack_name, 'disable_rollback': True, 'timeout_mins': 61, 'password': '******', 'template': None, 'parameters': IsA(dict), 'files': None } api.heat.stack_update(IsA(http.HttpRequest), stack_id=stack.id, **fields) api.neutron.network_list_for_tenant(IsA(http.HttpRequest), self.tenant.id) \ .AndReturn(self.networks.list()) self.mox.ReplayAll() url = reverse('horizon:project:stacks:change_template', args=[stack.id]) res = self.client.get(url) self.assertTemplateUsed(res, 'project/stacks/change_template.html') form_data = { 'template_source': 'raw', 'template_data': template.data, 'method': forms.ChangeTemplateForm.__name__ } res = self.client.post(url, form_data) url = reverse('horizon:project:stacks:edit_stack', args=[ stack.id, ]) form_data = { 'template_source': 'raw', 'template_data': template.data, 'password': '******', 'parameters': template.validate, 'stack_name': stack.stack_name, 'stack_id': stack.id, "timeout_mins": 61, "disable_rollback": True, "__param_DBUsername": "******", "__param_LinuxDistribution": "F17", "__param_InstanceType": "m1.small", "__param_KeyName": "test", "__param_DBPassword": "******", "__param_DBRootPassword": "******", "__param_DBName": "wordpress", "__param_Network": self.networks.list()[0]['id'], 'method': forms.EditStackForm.__name__ } res = self.client.post(url, form_data) self.assertRedirectsNoFollow(res, INDEX_URL)
def test_launch_stack_with_parameter_group(self): template = { 'data': ('heat_template_version: 2013-05-23\n' 'parameters:\n' ' last_param:\n' ' type: string\n' ' first_param:\n' ' type: string\n' ' middle_param:\n' ' type: string\n' 'parameter_groups:\n' '- parameters:\n' ' - first_param\n' ' - middle_param\n' ' - last_param\n'), 'validate': { 'Description': 'No description', 'Parameters': { 'last_param': { 'Label': 'last_param', 'Description': '', 'Type': 'String', 'NoEcho': 'false' }, 'first_param': { 'Label': 'first_param', 'Description': '', 'Type': 'String', 'NoEcho': 'false' }, 'middle_param': { 'Label': 'middle_param', 'Description': '', 'Type': 'String', 'NoEcho': 'true' } }, 'ParameterGroups': [ { 'parameters': [ 'first_param', 'middle_param', 'last_param' ] } ] } } api.heat.template_validate(IsA(http.HttpRequest), files={}, template=hc_format.parse(template['data'])) \ .AndReturn(template['validate']) self.mox.ReplayAll() url = reverse('horizon:project:stacks:select_template') res = self.client.get(url) self.assertTemplateUsed(res, 'project/stacks/select_template.html') form_data = {'template_source': 'raw', 'template_data': template['data'], 'method': forms.TemplateForm.__name__} res = self.client.post(url, form_data) self.assertTemplateUsed(res, 'project/stacks/create.html') # ensure the fields were rendered in the correct order regex = re.compile('^.*>first_param<.*>middle_param<.*>last_param<.*$', flags=re.DOTALL) self.assertRegexpMatches(res.content.decode('utf-8'), regex)
def test_launch_stack_with_environment(self): template = self.stack_templates.first() environment = self.stack_environments.first() stack = self.stacks.first() api.heat.template_validate( IsA(http.HttpRequest), files={}, template=hc_format.parse(template.data), environment=environment.data ).AndReturn(json.loads(template.validate)) api.heat.stack_create( IsA(http.HttpRequest), stack_name=stack.stack_name, timeout_mins=60, disable_rollback=True, template=None, environment=environment.data, parameters=IsA(dict), password="******", files=None, ) api.neutron.network_list_for_tenant(IsA(http.HttpRequest), self.tenant.id).AndReturn(self.networks.list()) api.neutron.network_list_for_tenant(IsA(http.HttpRequest), self.tenant.id).AndReturn(self.networks.list()) self.mox.ReplayAll() url = reverse("horizon:project:stacks:select_template") res = self.client.get(url) self.assertTemplateUsed(res, "project/stacks/select_template.html") form_data = { "template_source": "raw", "template_data": template.data, "environment_source": "raw", "environment_data": environment.data, "method": forms.TemplateForm.__name__, } res = self.client.post(url, form_data) self.assertTemplateUsed(res, "project/stacks/create.html") url = reverse("horizon:project:stacks:launch") form_data = { "template_source": "raw", "template_data": template.data, "environment_source": "raw", "environment_data": environment.data, "password": "******", "parameters": template.validate, "stack_name": stack.stack_name, "timeout_mins": 60, "disable_rollback": True, "__param_DBUsername": "******", "__param_LinuxDistribution": "F17", "__param_InstanceType": "m1.small", "__param_KeyName": "test", "__param_DBPassword": "******", "__param_DBRootPassword": "******", "__param_DBName": "wordpress", "__param_Network": self.networks.list()[0]["id"], "method": forms.CreateStackForm.__name__, } res = self.client.post(url, form_data) self.assertRedirectsNoFollow(res, INDEX_URL)
#!/usr/bin/env python # encoding=utf-8 from heatclient.common import template_format tmpl = ''' heat_template_version: 2013-05-23 resources: server1: type: OS::Nova::Server properties: flavor: m1.medium image: cirros user_data_format: RAW user_data: get_file: http://test.example/example ''' template_format.parse(tmpl)