/heat_integrationtests/functional/test_update_restricted.py

https://gitlab.com/unofficial-mirrors/openstack-heat
Python | 168 lines | 118 code | 30 blank | 20 comment | 2 complexity | 1f5ff5652248292b3761e0ef225de011 MD5 | raw file
  1. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  2. # not use this file except in compliance with the License. You may obtain
  3. # a copy of the License at
  4. #
  5. # http://www.apache.org/licenses/LICENSE-2.0
  6. #
  7. # Unless required by applicable law or agreed to in writing, software
  8. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  9. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  10. # License for the specific language governing permissions and limitations
  11. # under the License.
  12. import copy
  13. import time
  14. from heat_integrationtests.functional import functional_base
  15. test_template = {
  16. 'heat_template_version': '2013-05-23',
  17. 'description': 'Test template to create one instance.',
  18. 'resources': {
  19. 'bar': {
  20. 'type': 'OS::Heat::TestResource',
  21. 'properties': {
  22. 'value': '1234',
  23. 'update_replace': False,
  24. }
  25. }
  26. }
  27. }
  28. env_both_restrict = {u'resource_registry': {
  29. u'resources': {
  30. 'bar': {'restricted_actions': ['update', 'replace']}
  31. }
  32. }
  33. }
  34. env_replace_restrict = {u'resource_registry': {
  35. u'resources': {
  36. '*ar': {'restricted_actions': 'replace'}
  37. }
  38. }
  39. }
  40. reason_update_restrict = 'update is restricted for resource.'
  41. reason_replace_restrict = 'replace is restricted for resource.'
  42. class UpdateRestrictedStackTest(functional_base.FunctionalTestsBase):
  43. def _check_for_restriction_reason(self, events,
  44. reason, num_expected=1):
  45. matched = [e for e in events
  46. if e.resource_status_reason == reason]
  47. return len(matched) == num_expected
  48. def test_update(self):
  49. stack_identifier = self.stack_create(template=test_template)
  50. update_template = copy.deepcopy(test_template)
  51. props = update_template['resources']['bar']['properties']
  52. props['value'] = '4567'
  53. # check update fails - with 'both' restricted
  54. self.update_stack(stack_identifier, update_template,
  55. env_both_restrict,
  56. expected_status='UPDATE_FAILED')
  57. self.assertTrue(self.verify_resource_status(stack_identifier, 'bar',
  58. 'CREATE_COMPLETE'))
  59. resource_events = self.client.events.list(stack_identifier, 'bar')
  60. self.assertTrue(
  61. self._check_for_restriction_reason(resource_events,
  62. reason_update_restrict))
  63. # Ensure the timestamp changes, since this will be very quick
  64. time.sleep(1)
  65. # check update succeeds - with only 'replace' restricted
  66. self.update_stack(stack_identifier, update_template,
  67. env_replace_restrict,
  68. expected_status='UPDATE_COMPLETE')
  69. self.assertTrue(self.verify_resource_status(stack_identifier, 'bar',
  70. 'UPDATE_COMPLETE'))
  71. resource_events = self.client.events.list(stack_identifier, 'bar')
  72. self.assertFalse(
  73. self._check_for_restriction_reason(resource_events,
  74. reason_update_restrict, 2))
  75. self.assertTrue(
  76. self._check_for_restriction_reason(resource_events,
  77. reason_replace_restrict, 0))
  78. def test_replace(self):
  79. stack_identifier = self.stack_create(template=test_template)
  80. update_template = copy.deepcopy(test_template)
  81. props = update_template['resources']['bar']['properties']
  82. props['value'] = '4567'
  83. props['update_replace'] = True
  84. # check replace fails - with 'both' restricted
  85. self.update_stack(stack_identifier, update_template,
  86. env_both_restrict,
  87. expected_status='UPDATE_FAILED')
  88. self.assertTrue(self.verify_resource_status(stack_identifier, 'bar',
  89. 'CREATE_COMPLETE'))
  90. resource_events = self.client.events.list(stack_identifier, 'bar')
  91. self.assertTrue(
  92. self._check_for_restriction_reason(resource_events,
  93. reason_replace_restrict))
  94. # Ensure the timestamp changes, since this will be very quick
  95. time.sleep(1)
  96. # check replace fails - with only 'replace' restricted
  97. self.update_stack(stack_identifier, update_template,
  98. env_replace_restrict,
  99. expected_status='UPDATE_FAILED')
  100. self.assertTrue(self.verify_resource_status(stack_identifier, 'bar',
  101. 'CREATE_COMPLETE'))
  102. resource_events = self.client.events.list(stack_identifier, 'bar')
  103. self.assertTrue(
  104. self._check_for_restriction_reason(resource_events,
  105. reason_replace_restrict, 2))
  106. self.assertTrue(
  107. self._check_for_restriction_reason(resource_events,
  108. reason_update_restrict, 0))
  109. def test_update_type_changed(self):
  110. stack_identifier = self.stack_create(template=test_template)
  111. update_template = copy.deepcopy(test_template)
  112. rsrc = update_template['resources']['bar']
  113. rsrc['type'] = 'OS::Heat::None'
  114. # check replace fails - with 'both' restricted
  115. self.update_stack(stack_identifier, update_template,
  116. env_both_restrict,
  117. expected_status='UPDATE_FAILED')
  118. self.assertTrue(self.verify_resource_status(stack_identifier, 'bar',
  119. 'CREATE_COMPLETE'))
  120. resource_events = self.client.events.list(stack_identifier, 'bar')
  121. self.assertTrue(
  122. self._check_for_restriction_reason(resource_events,
  123. reason_replace_restrict))
  124. # Ensure the timestamp changes, since this will be very quick
  125. time.sleep(1)
  126. # check replace fails - with only 'replace' restricted
  127. self.update_stack(stack_identifier, update_template,
  128. env_replace_restrict,
  129. expected_status='UPDATE_FAILED')
  130. self.assertTrue(self.verify_resource_status(stack_identifier, 'bar',
  131. 'CREATE_COMPLETE'))
  132. resource_events = self.client.events.list(stack_identifier, 'bar')
  133. self.assertTrue(
  134. self._check_for_restriction_reason(resource_events,
  135. reason_replace_restrict, 2))
  136. self.assertTrue(
  137. self._check_for_restriction_reason(resource_events,
  138. reason_update_restrict, 0))