Allow referencing conditions by name
This change allows reference with other conditions by name in definition of a condition, something like: conditions: cd1: {equals: [{get_param: env_type}, 'prod']} cd2: {not: cd1} cd3: {equals: [{get_param: zone}, 'fujian']} cd4: {and: [cd1, cd3]} Change-Id: I6a0a00c23aa7d559dedd6998adaa7962d607f315 Co-Authored-By: huangtianhua <huangtianhua@huawei.com> Blueprint: support-conditions-function Related-Bug: #1621529
This commit is contained in:
parent
4090dfe926
commit
bca8b8e804
@ -842,7 +842,8 @@ expression
|
||||
or
|
||||
|
||||
Note: In condition functions, you can reference a value from an input
|
||||
parameter, but you cannot reference resource or its attribute.
|
||||
parameter, but you cannot reference resource or its attribute. We support
|
||||
referencing other conditions (by condition name) in condition functions.
|
||||
|
||||
An example of conditions section definition
|
||||
|
||||
@ -878,6 +879,12 @@ An example of conditions section definition
|
||||
- equals:
|
||||
- get_param: zone
|
||||
- beijing
|
||||
cd7:
|
||||
not: cd4
|
||||
cd8:
|
||||
and:
|
||||
- cd1
|
||||
- cd2
|
||||
|
||||
The example below shows how to associate condition with resources
|
||||
|
||||
@ -1592,9 +1599,9 @@ The syntax of the ``not`` function is
|
||||
|
||||
not: condition
|
||||
|
||||
Note: A condition such as ``equals`` that evaluates to true or false
|
||||
can be defined in ``not`` function, also we can set a boolean
|
||||
value as condition.
|
||||
Note: A condition can be an expression such as ``equals``, ``or`` and ``and``
|
||||
that evaluates to true or false, can be a boolean, and can be other condition
|
||||
name defined in ``conditions`` section of template.
|
||||
|
||||
Returns true for a condition that evaluates to false or
|
||||
returns false for a condition that evaluates to true.
|
||||
@ -1611,7 +1618,7 @@ For example
|
||||
If param 'env_type' equals to 'prod', this function returns false,
|
||||
otherwise returns true.
|
||||
|
||||
Another example
|
||||
Another example with boolean value definition
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
@ -1619,6 +1626,15 @@ Another example
|
||||
|
||||
This function returns false.
|
||||
|
||||
Another example reference other condition name
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
not: my_other_condition
|
||||
|
||||
This function returns false if my_other_condition evaluates to true,
|
||||
otherwise returns true.
|
||||
|
||||
and
|
||||
---
|
||||
The ``and`` function acts as an AND operator to evaluate all the
|
||||
@ -1630,9 +1646,9 @@ The syntax of the ``and`` function is
|
||||
|
||||
and: [{condition_1}, {condition_2}, ... {condition_n}]
|
||||
|
||||
Note: A condition such as ``equals`` or ``not`` that evaluates to true or
|
||||
false can be defined in ``and`` function, also we can set a boolean
|
||||
value as condition.
|
||||
Note: A condition can be an expression such as ``equals``, ``or`` and ``not``
|
||||
that evaluates to true or false, can be a boolean, and can be other condition
|
||||
names defined in ``conditions`` section of template.
|
||||
|
||||
Returns true if all the specified conditions evaluate to true, or returns
|
||||
false if any one of the conditions evaluates to false.
|
||||
@ -1653,6 +1669,17 @@ For example
|
||||
If param 'env_type' equals to 'prod', and param 'zone' is not equal to
|
||||
'beijing', this function returns true, otherwise returns false.
|
||||
|
||||
Another example reference with other conditions
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
and:
|
||||
- other_condition_1
|
||||
- other_condition_2
|
||||
|
||||
This function returns true if other_condition_1 and other_condition_2
|
||||
evaluate to true both, otherwise returns false.
|
||||
|
||||
or
|
||||
--
|
||||
The ``or`` function acts as an OR operator to evaluate all the
|
||||
@ -1664,9 +1691,9 @@ The syntax of the ``or`` function is
|
||||
|
||||
or: [{condition_1}, {condition_2}, ... {condition_n}]
|
||||
|
||||
Note: A condition such as ``equals`` or ``not`` that evaluates to true or
|
||||
false can be defined in ``or`` function, also we can set a boolean
|
||||
value as condition.
|
||||
Note: A condition can be an expression such as ``equals``, ``and`` and ``not``
|
||||
that evaluates to true or false, can be a boolean, and can be other condition
|
||||
names defined in ``conditions`` section of template.
|
||||
|
||||
Returns true if any one of the specified conditions evaluate to true,
|
||||
or returns false if all of the conditions evaluates to false.
|
||||
@ -1686,3 +1713,14 @@ For example
|
||||
|
||||
If param 'env_type' equals to 'prod', or the param 'zone' is not equal to
|
||||
'beijing', this function returns true, otherwise returns false.
|
||||
|
||||
Another example reference other conditions
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
or:
|
||||
- other_condition_1
|
||||
- other_condition_2
|
||||
|
||||
This function returns true if any one of other_condition_1 or
|
||||
other_condition_2 evaluate to true, otherwise returns false.
|
||||
|
@ -21,6 +21,9 @@ from heat.common import exception
|
||||
from heat.engine import function
|
||||
|
||||
|
||||
_in_progress = object()
|
||||
|
||||
|
||||
class Conditions(object):
|
||||
def __init__(self, conditions_dict):
|
||||
assert isinstance(conditions_dict, collections.Mapping)
|
||||
@ -55,8 +58,19 @@ class Conditions(object):
|
||||
raise ValueError(_('Invalid condition "%s"') % condition_name)
|
||||
|
||||
if condition_name not in self._resolved:
|
||||
self._resolved[condition_name] = _in_progress
|
||||
self._resolved[condition_name] = self._resolve(condition_name)
|
||||
return self._resolved[condition_name]
|
||||
|
||||
result = self._resolved[condition_name]
|
||||
|
||||
if result is _in_progress:
|
||||
message = _('Circular definition for condition '
|
||||
'"%s"') % condition_name
|
||||
raise exception.StackValidationFailed(
|
||||
error='Condition validation error',
|
||||
message=message)
|
||||
|
||||
return result
|
||||
|
||||
def __repr__(self):
|
||||
return 'Conditions(%r)' % self._conditions
|
||||
|
@ -1182,8 +1182,8 @@ class ConditionBoolean(function.Function):
|
||||
if isinstance(arg, bool):
|
||||
return arg
|
||||
|
||||
msg = _('The condition value must be a boolean: %s')
|
||||
raise ValueError(msg % arg)
|
||||
conditions = self.stack.t.conditions(self.stack)
|
||||
return conditions.is_enabled(arg)
|
||||
|
||||
|
||||
class Not(ConditionBoolean):
|
||||
|
@ -362,6 +362,32 @@ class TestTemplateConditionParser(common.HeatTestCase):
|
||||
self.assertIn('The definition of condition "prod_env" is invalid',
|
||||
six.text_type(ex))
|
||||
|
||||
def test_condition_reference_condition(self):
|
||||
t = {
|
||||
'heat_template_version': '2016-10-14',
|
||||
'parameters': {
|
||||
'env_type': {
|
||||
'type': 'string',
|
||||
'default': 'test'
|
||||
}
|
||||
},
|
||||
'conditions': {
|
||||
'prod_env': {'equals': [{'get_param': 'env_type'}, 'prod']},
|
||||
'test_env': {'not': 'prod_env'},
|
||||
'prod_or_test_env': {'or': ['prod_env', 'test_env']},
|
||||
'prod_and_test_env': {'and': ['prod_env', 'test_env']},
|
||||
}}
|
||||
|
||||
# test with get_attr in equals
|
||||
tmpl = template.Template(t)
|
||||
stk = stack.Stack(self.ctx, 'test_condition_reference', tmpl)
|
||||
conditions = tmpl.conditions(stk)
|
||||
|
||||
self.assertFalse(conditions.is_enabled('prod_env'))
|
||||
self.assertTrue(conditions.is_enabled('test_env'))
|
||||
self.assertTrue(conditions.is_enabled('prod_or_test_env'))
|
||||
self.assertFalse(conditions.is_enabled('prod_and_test_env'))
|
||||
|
||||
def test_get_res_condition_invalid(self):
|
||||
tmpl = copy.deepcopy(self.tmpl)
|
||||
# test condition name is invalid
|
||||
@ -392,6 +418,29 @@ class TestTemplateConditionParser(common.HeatTestCase):
|
||||
self.assertIn('Invalid condition "222"', six.text_type(ex))
|
||||
self.assertIn('outputs.foo.condition', six.text_type(ex))
|
||||
|
||||
def test_conditions_circular_ref(self):
|
||||
t = {
|
||||
'heat_template_version': '2016-10-14',
|
||||
'parameters': {
|
||||
'env_type': {
|
||||
'type': 'string',
|
||||
'default': 'test'
|
||||
}
|
||||
},
|
||||
'conditions': {
|
||||
'first_cond': {'not': 'second_cond'},
|
||||
'second_cond': {'not': 'third_cond'},
|
||||
'third_cond': {'not': 'first_cond'},
|
||||
}
|
||||
}
|
||||
tmpl = template.Template(t)
|
||||
stk = stack.Stack(self.ctx, 'test_condition_circular_ref', tmpl)
|
||||
conds = tmpl.conditions(stk)
|
||||
ex = self.assertRaises(exception.StackValidationFailed,
|
||||
conds.is_enabled, 'first_cond')
|
||||
self.assertIn('Circular definition for condition "first_cond"',
|
||||
six.text_type(ex))
|
||||
|
||||
|
||||
class TestTemplateValidate(common.HeatTestCase):
|
||||
|
||||
@ -958,12 +1007,13 @@ class TemplateTest(common.HeatTestCase):
|
||||
def test_not_invalid_args(self):
|
||||
tmpl = template.Template(aws_empty_template)
|
||||
|
||||
stk = stack.Stack(utils.dummy_context(),
|
||||
'test_not_invalid', tmpl)
|
||||
snippet = {'Fn::Not': ['invalid_arg']}
|
||||
exc = self.assertRaises(ValueError,
|
||||
self.resolve_condition, snippet, tmpl)
|
||||
self.resolve_condition, snippet, tmpl, stk)
|
||||
|
||||
error_msg = ('The condition value must be a boolean: '
|
||||
'invalid_arg')
|
||||
error_msg = 'Invalid condition "invalid_arg"'
|
||||
self.assertIn(error_msg, six.text_type(exc))
|
||||
# test invalid type
|
||||
snippet = {'Fn::Not': 'invalid'}
|
||||
@ -1036,11 +1086,11 @@ class TemplateTest(common.HeatTestCase):
|
||||
self.resolve_condition, snippet, tmpl)
|
||||
self.assertIn(error_msg, six.text_type(exc))
|
||||
|
||||
stk = stack.Stack(utils.dummy_context(), 'test_and_invalid', tmpl)
|
||||
snippet = {'Fn::And': ['cd1', True]}
|
||||
exc = self.assertRaises(ValueError,
|
||||
self.resolve_condition, snippet, tmpl)
|
||||
error_msg = ('The condition value must be a boolean: '
|
||||
'cd1')
|
||||
self.resolve_condition, snippet, tmpl, stk)
|
||||
error_msg = 'Invalid condition "cd1"'
|
||||
self.assertIn(error_msg, six.text_type(exc))
|
||||
|
||||
def test_or(self):
|
||||
@ -1097,11 +1147,11 @@ class TemplateTest(common.HeatTestCase):
|
||||
self.resolve_condition, snippet, tmpl)
|
||||
self.assertIn(error_msg, six.text_type(exc))
|
||||
|
||||
stk = stack.Stack(utils.dummy_context(), 'test_or_invalid', tmpl)
|
||||
snippet = {'Fn::Or': ['invalid_cd', True]}
|
||||
exc = self.assertRaises(ValueError,
|
||||
self.resolve_condition, snippet, tmpl)
|
||||
error_msg = ('The condition value must be a boolean: '
|
||||
'invalid_cd')
|
||||
self.resolve_condition, snippet, tmpl, stk)
|
||||
error_msg = 'Invalid condition "invalid_cd"'
|
||||
self.assertIn(error_msg, six.text_type(exc))
|
||||
|
||||
def test_join(self):
|
||||
|
@ -38,6 +38,14 @@ Conditions:
|
||||
- Fn::Equals:
|
||||
- Ref: zone
|
||||
- beijing
|
||||
Xian_Zone:
|
||||
Fn::Equals:
|
||||
- Ref: zone
|
||||
- xian
|
||||
Xianyang_Zone:
|
||||
Fn::Equals:
|
||||
- Ref: zone
|
||||
- xianyang
|
||||
Fujian_Zone:
|
||||
Fn::Or:
|
||||
- Fn::Equals:
|
||||
@ -46,6 +54,16 @@ Conditions:
|
||||
- Fn::Equals:
|
||||
- Ref: zone
|
||||
- xiamen
|
||||
Fujian_Prod:
|
||||
Fn::And:
|
||||
- Fujian_Zone
|
||||
- Prod
|
||||
Shannxi_Provice:
|
||||
Fn::Or:
|
||||
- Xian_Zone
|
||||
- Xianyang_Zone
|
||||
Not_Shannxi:
|
||||
Fn::Not: [Shannxi_Provice]
|
||||
Resources:
|
||||
test_res:
|
||||
Type: OS::Heat::TestResource
|
||||
@ -71,6 +89,21 @@ Resources:
|
||||
Condition: Fujian_Zone
|
||||
Properties:
|
||||
value: fujian_res
|
||||
fujian_prod_res:
|
||||
Type: OS::Heat::TestResource
|
||||
Condition: Fujian_Prod
|
||||
Properties:
|
||||
value: fujian_prod_res
|
||||
shannxi_res:
|
||||
Type: OS::Heat::TestResource
|
||||
Condition: Shannxi_Provice
|
||||
Properties:
|
||||
value: shannxi_res
|
||||
not_shannxi_res:
|
||||
Type: OS::Heat::TestResource
|
||||
Condition: Not_Shannxi
|
||||
Properties:
|
||||
value: not_shannxi_res
|
||||
Outputs:
|
||||
res_value:
|
||||
Value: {"Fn::GetAtt": [prod_res, output]}
|
||||
@ -112,6 +145,14 @@ conditions:
|
||||
- equals:
|
||||
- get_param: env_type
|
||||
- prod
|
||||
xian_zone:
|
||||
equals:
|
||||
- get_param: zone
|
||||
- xian
|
||||
xianyang_zone:
|
||||
equals:
|
||||
- get_param: zone
|
||||
- xianyang
|
||||
fujian_zone:
|
||||
or:
|
||||
- equals:
|
||||
@ -120,6 +161,16 @@ conditions:
|
||||
- equals:
|
||||
- get_param: zone
|
||||
- xiamen
|
||||
fujian_prod:
|
||||
and:
|
||||
- fujian_zone
|
||||
- prod
|
||||
shannxi_provice:
|
||||
or:
|
||||
- xian_zone
|
||||
- xianyang_zone
|
||||
not_shannxi:
|
||||
not: shannxi_provice
|
||||
resources:
|
||||
test_res:
|
||||
type: OS::Heat::TestResource
|
||||
@ -145,6 +196,21 @@ resources:
|
||||
condition: fujian_zone
|
||||
properties:
|
||||
value: fujian_res
|
||||
fujian_prod_res:
|
||||
type: OS::Heat::TestResource
|
||||
condition: fujian_prod
|
||||
properties:
|
||||
value: fujian_prod_res
|
||||
shannxi_res:
|
||||
type: OS::Heat::TestResource
|
||||
condition: shannxi_provice
|
||||
properties:
|
||||
value: shannxi_res
|
||||
not_shannxi_res:
|
||||
type: OS::Heat::TestResource
|
||||
condition: not_shannxi
|
||||
properties:
|
||||
value: not_shannxi_res
|
||||
outputs:
|
||||
res_value:
|
||||
value: {get_attr: [prod_res, output]}
|
||||
@ -244,30 +310,43 @@ class CreateUpdateResConditionTest(functional_base.FunctionalTestsBase):
|
||||
def setUp(self):
|
||||
super(CreateUpdateResConditionTest, self).setUp()
|
||||
|
||||
def res_assert_for_prod(self, resources, bj_prod=True, fj_zone=False):
|
||||
def res_assert_for_prod(self, resources, bj_prod=True, fj_zone=False,
|
||||
shannxi_provice=False):
|
||||
res_names = [res.resource_name for res in resources]
|
||||
if bj_prod:
|
||||
self.assertEqual(3, len(resources))
|
||||
self.assertEqual(4, len(resources))
|
||||
self.assertIn('beijing_prod_res', res_names)
|
||||
self.assertIn('not_shannxi_res', res_names)
|
||||
elif fj_zone:
|
||||
self.assertEqual(3, len(resources))
|
||||
self.assertEqual(5, len(resources))
|
||||
self.assertIn('fujian_res', res_names)
|
||||
self.assertNotIn('beijing_prod_res', res_names)
|
||||
self.assertIn('not_shannxi_res', res_names)
|
||||
self.assertIn('fujian_prod_res', res_names)
|
||||
elif shannxi_provice:
|
||||
self.assertEqual(3, len(resources))
|
||||
self.assertIn('shannxi_res', res_names)
|
||||
else:
|
||||
self.assertEqual(2, len(resources))
|
||||
self.assertEqual(3, len(resources))
|
||||
self.assertIn('not_shannxi_res', res_names)
|
||||
self.assertIn('prod_res', res_names)
|
||||
self.assertIn('test_res', res_names)
|
||||
|
||||
def res_assert_for_test(self, resources, fj_zone=False):
|
||||
def res_assert_for_test(self, resources, fj_zone=False,
|
||||
shannxi_provice=False):
|
||||
res_names = [res.resource_name for res in resources]
|
||||
|
||||
if fj_zone:
|
||||
self.assertEqual(3, len(resources))
|
||||
self.assertEqual(4, len(resources))
|
||||
self.assertIn('fujian_res', res_names)
|
||||
else:
|
||||
self.assertEqual(2, len(resources))
|
||||
self.assertIn('not_shannxi_res', res_names)
|
||||
elif shannxi_provice:
|
||||
self.assertEqual(3, len(resources))
|
||||
self.assertNotIn('fujian_res', res_names)
|
||||
|
||||
self.assertIn('shannxi_res', res_names)
|
||||
else:
|
||||
self.assertEqual(3, len(resources))
|
||||
self.assertIn('not_shannxi_res', res_names)
|
||||
self.assertIn('test_res', res_names)
|
||||
self.assertIn('test_res1', res_names)
|
||||
self.assertNotIn('prod_res', res_names)
|
||||
@ -334,6 +413,15 @@ class CreateUpdateResConditionTest(functional_base.FunctionalTestsBase):
|
||||
self.res_assert_for_test(resources, fj_zone=True)
|
||||
self.output_assert_for_test(stack_identifier)
|
||||
|
||||
parms = {'zone': 'xianyang'}
|
||||
self.update_stack(stack_identifier,
|
||||
template=cfn_template,
|
||||
parameters=parms)
|
||||
|
||||
resources = self.client.resources.list(stack_identifier)
|
||||
self.res_assert_for_test(resources, shannxi_provice=True)
|
||||
self.output_assert_for_test(stack_identifier)
|
||||
|
||||
parms = {'env_type': 'prod'}
|
||||
self.update_stack(stack_identifier,
|
||||
template=cfn_template,
|
||||
@ -363,6 +451,17 @@ class CreateUpdateResConditionTest(functional_base.FunctionalTestsBase):
|
||||
self.res_assert_for_prod(resources, bj_prod=False, fj_zone=True)
|
||||
self.output_assert_for_prod(stack_identifier, False)
|
||||
|
||||
parms = {'env_type': 'prod',
|
||||
'zone': 'xianyang'}
|
||||
self.update_stack(stack_identifier,
|
||||
template=cfn_template,
|
||||
parameters=parms)
|
||||
|
||||
resources = self.client.resources.list(stack_identifier)
|
||||
self.res_assert_for_prod(resources, bj_prod=False, fj_zone=False,
|
||||
shannxi_provice=True)
|
||||
self.output_assert_for_prod(stack_identifier, False)
|
||||
|
||||
def test_stack_create_update_cfn_template_prod_to_test(self):
|
||||
parms = {'env_type': 'prod'}
|
||||
stack_identifier = self.stack_create(template=cfn_template,
|
||||
@ -381,6 +480,28 @@ class CreateUpdateResConditionTest(functional_base.FunctionalTestsBase):
|
||||
self.res_assert_for_prod(resources, bj_prod=False, fj_zone=True)
|
||||
self.output_assert_for_prod(stack_identifier, bj_prod=False)
|
||||
|
||||
parms = {'zone': 'xianyang',
|
||||
'env_type': 'prod'}
|
||||
self.update_stack(stack_identifier,
|
||||
template=cfn_template,
|
||||
parameters=parms)
|
||||
|
||||
resources = self.client.resources.list(stack_identifier)
|
||||
self.res_assert_for_prod(resources, bj_prod=False, fj_zone=False,
|
||||
shannxi_provice=True)
|
||||
self.output_assert_for_prod(stack_identifier, bj_prod=False)
|
||||
|
||||
parms = {'zone': 'shanghai',
|
||||
'env_type': 'prod'}
|
||||
self.update_stack(stack_identifier,
|
||||
template=cfn_template,
|
||||
parameters=parms)
|
||||
|
||||
resources = self.client.resources.list(stack_identifier)
|
||||
self.res_assert_for_prod(resources, bj_prod=False, fj_zone=False,
|
||||
shannxi_provice=False)
|
||||
self.output_assert_for_prod(stack_identifier, bj_prod=False)
|
||||
|
||||
parms = {'env_type': 'test'}
|
||||
self.update_stack(stack_identifier,
|
||||
template=cfn_template,
|
||||
@ -400,12 +521,32 @@ class CreateUpdateResConditionTest(functional_base.FunctionalTestsBase):
|
||||
self.res_assert_for_test(resources, fj_zone=True)
|
||||
self.output_assert_for_test(stack_identifier)
|
||||
|
||||
parms = {'env_type': 'test',
|
||||
'zone': 'xianyang'}
|
||||
self.update_stack(stack_identifier,
|
||||
template=cfn_template,
|
||||
parameters=parms)
|
||||
|
||||
resources = self.client.resources.list(stack_identifier)
|
||||
self.res_assert_for_test(resources, fj_zone=False,
|
||||
shannxi_provice=True)
|
||||
self.output_assert_for_test(stack_identifier)
|
||||
|
||||
def test_stack_create_update_hot_template_test_to_prod(self):
|
||||
stack_identifier = self.stack_create(template=hot_template)
|
||||
resources = self.client.resources.list(stack_identifier)
|
||||
self.res_assert_for_test(resources)
|
||||
self.output_assert_for_test(stack_identifier)
|
||||
|
||||
parms = {'zone': 'xianyang'}
|
||||
self.update_stack(stack_identifier,
|
||||
template=hot_template,
|
||||
parameters=parms)
|
||||
|
||||
resources = self.client.resources.list(stack_identifier)
|
||||
self.res_assert_for_test(resources, shannxi_provice=True)
|
||||
self.output_assert_for_test(stack_identifier)
|
||||
|
||||
parms = {'env_type': 'prod'}
|
||||
self.update_stack(stack_identifier,
|
||||
template=hot_template,
|
||||
@ -425,6 +566,16 @@ class CreateUpdateResConditionTest(functional_base.FunctionalTestsBase):
|
||||
self.res_assert_for_prod(resources, False)
|
||||
self.output_assert_for_prod(stack_identifier, False)
|
||||
|
||||
parms = {'env_type': 'prod',
|
||||
'zone': 'xianyang'}
|
||||
self.update_stack(stack_identifier,
|
||||
template=hot_template,
|
||||
parameters=parms)
|
||||
|
||||
resources = self.client.resources.list(stack_identifier)
|
||||
self.res_assert_for_prod(resources, False, shannxi_provice=True)
|
||||
self.output_assert_for_prod(stack_identifier, False)
|
||||
|
||||
def test_stack_create_update_hot_template_prod_to_test(self):
|
||||
parms = {'env_type': 'prod'}
|
||||
stack_identifier = self.stack_create(template=hot_template,
|
||||
@ -433,6 +584,16 @@ class CreateUpdateResConditionTest(functional_base.FunctionalTestsBase):
|
||||
self.res_assert_for_prod(resources)
|
||||
self.output_assert_for_prod(stack_identifier)
|
||||
|
||||
parms = {'env_type': 'prod',
|
||||
'zone': 'xianyang'}
|
||||
self.update_stack(stack_identifier,
|
||||
template=hot_template,
|
||||
parameters=parms)
|
||||
|
||||
resources = self.client.resources.list(stack_identifier)
|
||||
self.res_assert_for_prod(resources, False, shannxi_provice=True)
|
||||
self.output_assert_for_prod(stack_identifier, False)
|
||||
|
||||
parms = {'env_type': 'test'}
|
||||
self.update_stack(stack_identifier,
|
||||
template=hot_template,
|
||||
@ -442,6 +603,17 @@ class CreateUpdateResConditionTest(functional_base.FunctionalTestsBase):
|
||||
self.res_assert_for_test(resources)
|
||||
self.output_assert_for_test(stack_identifier)
|
||||
|
||||
parms = {'env_type': 'test',
|
||||
'zone': 'xianyang'}
|
||||
self.update_stack(stack_identifier,
|
||||
template=hot_template,
|
||||
parameters=parms)
|
||||
|
||||
resources = self.client.resources.list(stack_identifier)
|
||||
self.res_assert_for_test(resources, fj_zone=False,
|
||||
shannxi_provice=True)
|
||||
self.output_assert_for_test(stack_identifier)
|
||||
|
||||
def test_condition_rename(self):
|
||||
stack_identifier = self.stack_create(template=before_rename_tmpl)
|
||||
self.update_stack(stack_identifier, template=after_rename_tmpl)
|
||||
|
Loading…
Reference in New Issue
Block a user