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
|
or
|
||||||
|
|
||||||
Note: In condition functions, you can reference a value from an input
|
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
|
An example of conditions section definition
|
||||||
|
|
||||||
@ -878,6 +879,12 @@ An example of conditions section definition
|
|||||||
- equals:
|
- equals:
|
||||||
- get_param: zone
|
- get_param: zone
|
||||||
- beijing
|
- beijing
|
||||||
|
cd7:
|
||||||
|
not: cd4
|
||||||
|
cd8:
|
||||||
|
and:
|
||||||
|
- cd1
|
||||||
|
- cd2
|
||||||
|
|
||||||
The example below shows how to associate condition with resources
|
The example below shows how to associate condition with resources
|
||||||
|
|
||||||
@ -1592,9 +1599,9 @@ The syntax of the ``not`` function is
|
|||||||
|
|
||||||
not: condition
|
not: condition
|
||||||
|
|
||||||
Note: A condition such as ``equals`` that evaluates to true or false
|
Note: A condition can be an expression such as ``equals``, ``or`` and ``and``
|
||||||
can be defined in ``not`` function, also we can set a boolean
|
that evaluates to true or false, can be a boolean, and can be other condition
|
||||||
value as condition.
|
name defined in ``conditions`` section of template.
|
||||||
|
|
||||||
Returns true for a condition that evaluates to false or
|
Returns true for a condition that evaluates to false or
|
||||||
returns false for a condition that evaluates to true.
|
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,
|
If param 'env_type' equals to 'prod', this function returns false,
|
||||||
otherwise returns true.
|
otherwise returns true.
|
||||||
|
|
||||||
Another example
|
Another example with boolean value definition
|
||||||
|
|
||||||
.. code-block:: yaml
|
.. code-block:: yaml
|
||||||
|
|
||||||
@ -1619,6 +1626,15 @@ Another example
|
|||||||
|
|
||||||
This function returns false.
|
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
|
and
|
||||||
---
|
---
|
||||||
The ``and`` function acts as an AND operator to evaluate all the
|
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}]
|
and: [{condition_1}, {condition_2}, ... {condition_n}]
|
||||||
|
|
||||||
Note: A condition such as ``equals`` or ``not`` that evaluates to true or
|
Note: A condition can be an expression such as ``equals``, ``or`` and ``not``
|
||||||
false can be defined in ``and`` function, also we can set a boolean
|
that evaluates to true or false, can be a boolean, and can be other condition
|
||||||
value as condition.
|
names defined in ``conditions`` section of template.
|
||||||
|
|
||||||
Returns true if all the specified conditions evaluate to true, or returns
|
Returns true if all the specified conditions evaluate to true, or returns
|
||||||
false if any one of the conditions evaluates to false.
|
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
|
If param 'env_type' equals to 'prod', and param 'zone' is not equal to
|
||||||
'beijing', this function returns true, otherwise returns false.
|
'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
|
or
|
||||||
--
|
--
|
||||||
The ``or`` function acts as an OR operator to evaluate all the
|
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}]
|
or: [{condition_1}, {condition_2}, ... {condition_n}]
|
||||||
|
|
||||||
Note: A condition such as ``equals`` or ``not`` that evaluates to true or
|
Note: A condition can be an expression such as ``equals``, ``and`` and ``not``
|
||||||
false can be defined in ``or`` function, also we can set a boolean
|
that evaluates to true or false, can be a boolean, and can be other condition
|
||||||
value as condition.
|
names defined in ``conditions`` section of template.
|
||||||
|
|
||||||
Returns true if any one of the specified conditions evaluate to true,
|
Returns true if any one of the specified conditions evaluate to true,
|
||||||
or returns false if all of the conditions evaluates to false.
|
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
|
If param 'env_type' equals to 'prod', or the param 'zone' is not equal to
|
||||||
'beijing', this function returns true, otherwise returns false.
|
'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
|
from heat.engine import function
|
||||||
|
|
||||||
|
|
||||||
|
_in_progress = object()
|
||||||
|
|
||||||
|
|
||||||
class Conditions(object):
|
class Conditions(object):
|
||||||
def __init__(self, conditions_dict):
|
def __init__(self, conditions_dict):
|
||||||
assert isinstance(conditions_dict, collections.Mapping)
|
assert isinstance(conditions_dict, collections.Mapping)
|
||||||
@ -55,8 +58,19 @@ class Conditions(object):
|
|||||||
raise ValueError(_('Invalid condition "%s"') % condition_name)
|
raise ValueError(_('Invalid condition "%s"') % condition_name)
|
||||||
|
|
||||||
if condition_name not in self._resolved:
|
if condition_name not in self._resolved:
|
||||||
|
self._resolved[condition_name] = _in_progress
|
||||||
self._resolved[condition_name] = self._resolve(condition_name)
|
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):
|
def __repr__(self):
|
||||||
return 'Conditions(%r)' % self._conditions
|
return 'Conditions(%r)' % self._conditions
|
||||||
|
@ -1182,8 +1182,8 @@ class ConditionBoolean(function.Function):
|
|||||||
if isinstance(arg, bool):
|
if isinstance(arg, bool):
|
||||||
return arg
|
return arg
|
||||||
|
|
||||||
msg = _('The condition value must be a boolean: %s')
|
conditions = self.stack.t.conditions(self.stack)
|
||||||
raise ValueError(msg % arg)
|
return conditions.is_enabled(arg)
|
||||||
|
|
||||||
|
|
||||||
class Not(ConditionBoolean):
|
class Not(ConditionBoolean):
|
||||||
|
@ -362,6 +362,32 @@ class TestTemplateConditionParser(common.HeatTestCase):
|
|||||||
self.assertIn('The definition of condition "prod_env" is invalid',
|
self.assertIn('The definition of condition "prod_env" is invalid',
|
||||||
six.text_type(ex))
|
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):
|
def test_get_res_condition_invalid(self):
|
||||||
tmpl = copy.deepcopy(self.tmpl)
|
tmpl = copy.deepcopy(self.tmpl)
|
||||||
# test condition name is invalid
|
# test condition name is invalid
|
||||||
@ -392,6 +418,29 @@ class TestTemplateConditionParser(common.HeatTestCase):
|
|||||||
self.assertIn('Invalid condition "222"', six.text_type(ex))
|
self.assertIn('Invalid condition "222"', six.text_type(ex))
|
||||||
self.assertIn('outputs.foo.condition', 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):
|
class TestTemplateValidate(common.HeatTestCase):
|
||||||
|
|
||||||
@ -958,12 +1007,13 @@ class TemplateTest(common.HeatTestCase):
|
|||||||
def test_not_invalid_args(self):
|
def test_not_invalid_args(self):
|
||||||
tmpl = template.Template(aws_empty_template)
|
tmpl = template.Template(aws_empty_template)
|
||||||
|
|
||||||
|
stk = stack.Stack(utils.dummy_context(),
|
||||||
|
'test_not_invalid', tmpl)
|
||||||
snippet = {'Fn::Not': ['invalid_arg']}
|
snippet = {'Fn::Not': ['invalid_arg']}
|
||||||
exc = self.assertRaises(ValueError,
|
exc = self.assertRaises(ValueError,
|
||||||
self.resolve_condition, snippet, tmpl)
|
self.resolve_condition, snippet, tmpl, stk)
|
||||||
|
|
||||||
error_msg = ('The condition value must be a boolean: '
|
error_msg = 'Invalid condition "invalid_arg"'
|
||||||
'invalid_arg')
|
|
||||||
self.assertIn(error_msg, six.text_type(exc))
|
self.assertIn(error_msg, six.text_type(exc))
|
||||||
# test invalid type
|
# test invalid type
|
||||||
snippet = {'Fn::Not': 'invalid'}
|
snippet = {'Fn::Not': 'invalid'}
|
||||||
@ -1036,11 +1086,11 @@ class TemplateTest(common.HeatTestCase):
|
|||||||
self.resolve_condition, snippet, tmpl)
|
self.resolve_condition, snippet, tmpl)
|
||||||
self.assertIn(error_msg, six.text_type(exc))
|
self.assertIn(error_msg, six.text_type(exc))
|
||||||
|
|
||||||
|
stk = stack.Stack(utils.dummy_context(), 'test_and_invalid', tmpl)
|
||||||
snippet = {'Fn::And': ['cd1', True]}
|
snippet = {'Fn::And': ['cd1', True]}
|
||||||
exc = self.assertRaises(ValueError,
|
exc = self.assertRaises(ValueError,
|
||||||
self.resolve_condition, snippet, tmpl)
|
self.resolve_condition, snippet, tmpl, stk)
|
||||||
error_msg = ('The condition value must be a boolean: '
|
error_msg = 'Invalid condition "cd1"'
|
||||||
'cd1')
|
|
||||||
self.assertIn(error_msg, six.text_type(exc))
|
self.assertIn(error_msg, six.text_type(exc))
|
||||||
|
|
||||||
def test_or(self):
|
def test_or(self):
|
||||||
@ -1097,11 +1147,11 @@ class TemplateTest(common.HeatTestCase):
|
|||||||
self.resolve_condition, snippet, tmpl)
|
self.resolve_condition, snippet, tmpl)
|
||||||
self.assertIn(error_msg, six.text_type(exc))
|
self.assertIn(error_msg, six.text_type(exc))
|
||||||
|
|
||||||
|
stk = stack.Stack(utils.dummy_context(), 'test_or_invalid', tmpl)
|
||||||
snippet = {'Fn::Or': ['invalid_cd', True]}
|
snippet = {'Fn::Or': ['invalid_cd', True]}
|
||||||
exc = self.assertRaises(ValueError,
|
exc = self.assertRaises(ValueError,
|
||||||
self.resolve_condition, snippet, tmpl)
|
self.resolve_condition, snippet, tmpl, stk)
|
||||||
error_msg = ('The condition value must be a boolean: '
|
error_msg = 'Invalid condition "invalid_cd"'
|
||||||
'invalid_cd')
|
|
||||||
self.assertIn(error_msg, six.text_type(exc))
|
self.assertIn(error_msg, six.text_type(exc))
|
||||||
|
|
||||||
def test_join(self):
|
def test_join(self):
|
||||||
|
@ -38,6 +38,14 @@ Conditions:
|
|||||||
- Fn::Equals:
|
- Fn::Equals:
|
||||||
- Ref: zone
|
- Ref: zone
|
||||||
- beijing
|
- beijing
|
||||||
|
Xian_Zone:
|
||||||
|
Fn::Equals:
|
||||||
|
- Ref: zone
|
||||||
|
- xian
|
||||||
|
Xianyang_Zone:
|
||||||
|
Fn::Equals:
|
||||||
|
- Ref: zone
|
||||||
|
- xianyang
|
||||||
Fujian_Zone:
|
Fujian_Zone:
|
||||||
Fn::Or:
|
Fn::Or:
|
||||||
- Fn::Equals:
|
- Fn::Equals:
|
||||||
@ -46,6 +54,16 @@ Conditions:
|
|||||||
- Fn::Equals:
|
- Fn::Equals:
|
||||||
- Ref: zone
|
- Ref: zone
|
||||||
- xiamen
|
- xiamen
|
||||||
|
Fujian_Prod:
|
||||||
|
Fn::And:
|
||||||
|
- Fujian_Zone
|
||||||
|
- Prod
|
||||||
|
Shannxi_Provice:
|
||||||
|
Fn::Or:
|
||||||
|
- Xian_Zone
|
||||||
|
- Xianyang_Zone
|
||||||
|
Not_Shannxi:
|
||||||
|
Fn::Not: [Shannxi_Provice]
|
||||||
Resources:
|
Resources:
|
||||||
test_res:
|
test_res:
|
||||||
Type: OS::Heat::TestResource
|
Type: OS::Heat::TestResource
|
||||||
@ -71,6 +89,21 @@ Resources:
|
|||||||
Condition: Fujian_Zone
|
Condition: Fujian_Zone
|
||||||
Properties:
|
Properties:
|
||||||
value: fujian_res
|
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:
|
Outputs:
|
||||||
res_value:
|
res_value:
|
||||||
Value: {"Fn::GetAtt": [prod_res, output]}
|
Value: {"Fn::GetAtt": [prod_res, output]}
|
||||||
@ -112,6 +145,14 @@ conditions:
|
|||||||
- equals:
|
- equals:
|
||||||
- get_param: env_type
|
- get_param: env_type
|
||||||
- prod
|
- prod
|
||||||
|
xian_zone:
|
||||||
|
equals:
|
||||||
|
- get_param: zone
|
||||||
|
- xian
|
||||||
|
xianyang_zone:
|
||||||
|
equals:
|
||||||
|
- get_param: zone
|
||||||
|
- xianyang
|
||||||
fujian_zone:
|
fujian_zone:
|
||||||
or:
|
or:
|
||||||
- equals:
|
- equals:
|
||||||
@ -120,6 +161,16 @@ conditions:
|
|||||||
- equals:
|
- equals:
|
||||||
- get_param: zone
|
- get_param: zone
|
||||||
- xiamen
|
- xiamen
|
||||||
|
fujian_prod:
|
||||||
|
and:
|
||||||
|
- fujian_zone
|
||||||
|
- prod
|
||||||
|
shannxi_provice:
|
||||||
|
or:
|
||||||
|
- xian_zone
|
||||||
|
- xianyang_zone
|
||||||
|
not_shannxi:
|
||||||
|
not: shannxi_provice
|
||||||
resources:
|
resources:
|
||||||
test_res:
|
test_res:
|
||||||
type: OS::Heat::TestResource
|
type: OS::Heat::TestResource
|
||||||
@ -145,6 +196,21 @@ resources:
|
|||||||
condition: fujian_zone
|
condition: fujian_zone
|
||||||
properties:
|
properties:
|
||||||
value: fujian_res
|
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:
|
outputs:
|
||||||
res_value:
|
res_value:
|
||||||
value: {get_attr: [prod_res, output]}
|
value: {get_attr: [prod_res, output]}
|
||||||
@ -244,30 +310,43 @@ class CreateUpdateResConditionTest(functional_base.FunctionalTestsBase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(CreateUpdateResConditionTest, self).setUp()
|
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]
|
res_names = [res.resource_name for res in resources]
|
||||||
if bj_prod:
|
if bj_prod:
|
||||||
self.assertEqual(3, len(resources))
|
self.assertEqual(4, len(resources))
|
||||||
self.assertIn('beijing_prod_res', res_names)
|
self.assertIn('beijing_prod_res', res_names)
|
||||||
|
self.assertIn('not_shannxi_res', res_names)
|
||||||
elif fj_zone:
|
elif fj_zone:
|
||||||
self.assertEqual(3, len(resources))
|
self.assertEqual(5, len(resources))
|
||||||
self.assertIn('fujian_res', res_names)
|
self.assertIn('fujian_res', res_names)
|
||||||
self.assertNotIn('beijing_prod_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:
|
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('prod_res', res_names)
|
||||||
self.assertIn('test_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]
|
res_names = [res.resource_name for res in resources]
|
||||||
|
|
||||||
if fj_zone:
|
if fj_zone:
|
||||||
self.assertEqual(3, len(resources))
|
self.assertEqual(4, len(resources))
|
||||||
self.assertIn('fujian_res', res_names)
|
self.assertIn('fujian_res', res_names)
|
||||||
else:
|
self.assertIn('not_shannxi_res', res_names)
|
||||||
self.assertEqual(2, len(resources))
|
elif shannxi_provice:
|
||||||
|
self.assertEqual(3, len(resources))
|
||||||
self.assertNotIn('fujian_res', res_names)
|
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_res', res_names)
|
||||||
self.assertIn('test_res1', res_names)
|
self.assertIn('test_res1', res_names)
|
||||||
self.assertNotIn('prod_res', 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.res_assert_for_test(resources, fj_zone=True)
|
||||||
self.output_assert_for_test(stack_identifier)
|
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'}
|
parms = {'env_type': 'prod'}
|
||||||
self.update_stack(stack_identifier,
|
self.update_stack(stack_identifier,
|
||||||
template=cfn_template,
|
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.res_assert_for_prod(resources, bj_prod=False, fj_zone=True)
|
||||||
self.output_assert_for_prod(stack_identifier, False)
|
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):
|
def test_stack_create_update_cfn_template_prod_to_test(self):
|
||||||
parms = {'env_type': 'prod'}
|
parms = {'env_type': 'prod'}
|
||||||
stack_identifier = self.stack_create(template=cfn_template,
|
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.res_assert_for_prod(resources, bj_prod=False, fj_zone=True)
|
||||||
self.output_assert_for_prod(stack_identifier, bj_prod=False)
|
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'}
|
parms = {'env_type': 'test'}
|
||||||
self.update_stack(stack_identifier,
|
self.update_stack(stack_identifier,
|
||||||
template=cfn_template,
|
template=cfn_template,
|
||||||
@ -400,12 +521,32 @@ class CreateUpdateResConditionTest(functional_base.FunctionalTestsBase):
|
|||||||
self.res_assert_for_test(resources, fj_zone=True)
|
self.res_assert_for_test(resources, fj_zone=True)
|
||||||
self.output_assert_for_test(stack_identifier)
|
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):
|
def test_stack_create_update_hot_template_test_to_prod(self):
|
||||||
stack_identifier = self.stack_create(template=hot_template)
|
stack_identifier = self.stack_create(template=hot_template)
|
||||||
resources = self.client.resources.list(stack_identifier)
|
resources = self.client.resources.list(stack_identifier)
|
||||||
self.res_assert_for_test(resources)
|
self.res_assert_for_test(resources)
|
||||||
self.output_assert_for_test(stack_identifier)
|
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'}
|
parms = {'env_type': 'prod'}
|
||||||
self.update_stack(stack_identifier,
|
self.update_stack(stack_identifier,
|
||||||
template=hot_template,
|
template=hot_template,
|
||||||
@ -425,6 +566,16 @@ class CreateUpdateResConditionTest(functional_base.FunctionalTestsBase):
|
|||||||
self.res_assert_for_prod(resources, False)
|
self.res_assert_for_prod(resources, False)
|
||||||
self.output_assert_for_prod(stack_identifier, 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):
|
def test_stack_create_update_hot_template_prod_to_test(self):
|
||||||
parms = {'env_type': 'prod'}
|
parms = {'env_type': 'prod'}
|
||||||
stack_identifier = self.stack_create(template=hot_template,
|
stack_identifier = self.stack_create(template=hot_template,
|
||||||
@ -433,6 +584,16 @@ class CreateUpdateResConditionTest(functional_base.FunctionalTestsBase):
|
|||||||
self.res_assert_for_prod(resources)
|
self.res_assert_for_prod(resources)
|
||||||
self.output_assert_for_prod(stack_identifier)
|
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'}
|
parms = {'env_type': 'test'}
|
||||||
self.update_stack(stack_identifier,
|
self.update_stack(stack_identifier,
|
||||||
template=hot_template,
|
template=hot_template,
|
||||||
@ -442,6 +603,17 @@ class CreateUpdateResConditionTest(functional_base.FunctionalTestsBase):
|
|||||||
self.res_assert_for_test(resources)
|
self.res_assert_for_test(resources)
|
||||||
self.output_assert_for_test(stack_identifier)
|
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):
|
def test_condition_rename(self):
|
||||||
stack_identifier = self.stack_create(template=before_rename_tmpl)
|
stack_identifier = self.stack_create(template=before_rename_tmpl)
|
||||||
self.update_stack(stack_identifier, template=after_rename_tmpl)
|
self.update_stack(stack_identifier, template=after_rename_tmpl)
|
||||||
|
Loading…
Reference in New Issue
Block a user