Add OS::Heat::None resource
Adds a new resource, designed to enable easy "stubbing out" of resources via the environment resource_registry. It takes any properties, and returns any attribute (as None), meaning it can be uses in place of "noop" nested stacks which dummy an existing resources by matching parameters/outputs to properties/attributes. Implements: blueprint noop-resource Change-Id: Idc485a9fcf7287030dda22f893486279be9e1a68
This commit is contained in:
parent
bd7895c555
commit
8f02c9b540
56
heat/engine/resources/openstack/heat/none_resource.py
Normal file
56
heat/engine/resources/openstack/heat/none_resource.py
Normal file
@ -0,0 +1,56 @@
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import six
|
||||
import uuid
|
||||
|
||||
from heat.engine import properties
|
||||
from heat.engine import resource
|
||||
from heat.engine import support
|
||||
|
||||
|
||||
class NoneResource(resource.Resource):
|
||||
'''
|
||||
A resource which enables easily disabling certain resources via the
|
||||
resource_registry. It does nothing, but can effectively stub out
|
||||
any other resource because it will accept any properties and return
|
||||
any attribute (as None). Note this resource always does nothing
|
||||
on update (e.g it is not replaced even if a change to the stubbed
|
||||
resource properties would cause replacement).
|
||||
'''
|
||||
|
||||
support_status = support.SupportStatus(version='5.0.0')
|
||||
properties_schema = {}
|
||||
attributes_schema = {}
|
||||
|
||||
def _needs_update(self, after, before, after_props, before_props,
|
||||
prev_resource):
|
||||
return False
|
||||
|
||||
def reparse(self):
|
||||
self.properties = properties.Properties(schema={}, data={})
|
||||
|
||||
def handle_create(self):
|
||||
self.resource_id_set(six.text_type(uuid.uuid4()))
|
||||
|
||||
def validate(self):
|
||||
pass
|
||||
|
||||
def FnGetAtt(self, key, *path):
|
||||
return None
|
||||
|
||||
|
||||
def resource_mapping():
|
||||
return {
|
||||
'OS::Heat::None': NoneResource,
|
||||
}
|
77
heat/tests/test_none_resource.py
Normal file
77
heat/tests/test_none_resource.py
Normal file
@ -0,0 +1,77 @@
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from heat.common import template_format
|
||||
from heat.tests import common
|
||||
from heat.tests import utils
|
||||
|
||||
|
||||
class NoneResourceTest(common.HeatTestCase):
|
||||
|
||||
tmpl = '''
|
||||
heat_template_version: 2015-10-15
|
||||
resources:
|
||||
none:
|
||||
type: OS::Heat::None
|
||||
properties:
|
||||
ignored: foo
|
||||
outputs:
|
||||
anything:
|
||||
value: {get_attr: [none, anything]}
|
||||
'''
|
||||
|
||||
def _create_none_stack(self):
|
||||
self.t = template_format.parse(self.tmpl)
|
||||
self.stack = utils.parse_stack(self.t)
|
||||
self.rsrc = self.stack['none']
|
||||
self.assertIsNone(self.rsrc.validate())
|
||||
self.stack.create()
|
||||
self.assertEqual(self.rsrc.CREATE, self.rsrc.action)
|
||||
self.assertEqual(self.rsrc.COMPLETE, self.rsrc.status)
|
||||
self.assertEqual(self.stack.CREATE, self.stack.action)
|
||||
self.assertEqual(self.stack.COMPLETE, self.stack.status)
|
||||
self.assertEqual(None, self.stack.output('anything'))
|
||||
|
||||
def test_none_stack_create(self):
|
||||
self._create_none_stack()
|
||||
|
||||
def test_none_stack_update_nochange(self):
|
||||
self._create_none_stack()
|
||||
before_refid = self.rsrc.FnGetRefId()
|
||||
self.assertIsNotNone(before_refid)
|
||||
utils.update_stack(self.stack, self.t)
|
||||
self.assertEqual((self.stack.UPDATE, self.stack.COMPLETE),
|
||||
self.stack.state)
|
||||
self.assertEqual(before_refid, self.stack['none'].FnGetRefId())
|
||||
|
||||
def test_none_stack_update_add_prop(self):
|
||||
self._create_none_stack()
|
||||
before_refid = self.rsrc.FnGetRefId()
|
||||
self.assertIsNotNone(before_refid)
|
||||
new_t = self.t.copy()
|
||||
new_t['resources']['none']['properties']['another'] = 123
|
||||
utils.update_stack(self.stack, new_t)
|
||||
self.assertEqual((self.stack.UPDATE, self.stack.COMPLETE),
|
||||
self.stack.state)
|
||||
self.assertEqual(before_refid, self.stack['none'].FnGetRefId())
|
||||
|
||||
def test_none_stack_update_del_prop(self):
|
||||
self._create_none_stack()
|
||||
before_refid = self.rsrc.FnGetRefId()
|
||||
self.assertIsNotNone(before_refid)
|
||||
new_t = self.t.copy()
|
||||
del(new_t['resources']['none']['properties']['ignored'])
|
||||
utils.update_stack(self.stack, new_t)
|
||||
self.assertEqual((self.stack.UPDATE, self.stack.COMPLETE),
|
||||
self.stack.state)
|
||||
self.assertEqual(before_refid, self.stack['none'].FnGetRefId())
|
@ -102,6 +102,15 @@ def parse_stack(t, params=None, files=None, stack_name=None,
|
||||
return stk
|
||||
|
||||
|
||||
def update_stack(stk, new_t, params=None, files=None):
|
||||
ctx = dummy_context()
|
||||
templ = template.Template(new_t, files=files,
|
||||
env=environment.Environment(params))
|
||||
updated_stack = stack.Stack(ctx, 'updated_stack', templ)
|
||||
|
||||
stk.update(updated_stack)
|
||||
|
||||
|
||||
class PhysName(object):
|
||||
|
||||
mock_short_id = 'x' * 12
|
||||
|
Loading…
x
Reference in New Issue
Block a user