support nested stack in heat
* add the depth of the nested stack 10 should be enough consider making it configurable Change-Id: I9903aa760801170b9d1c2d23fbea79d80e5e959d
This commit is contained in:
parent
30e3337a7d
commit
bb46cd5232
1
.gitignore
vendored
1
.gitignore
vendored
@ -25,6 +25,7 @@ ChangeLog
|
||||
cover
|
||||
etc/vitrage/vitrage.conf
|
||||
doc/source/_static/
|
||||
*.db
|
||||
|
||||
#Python
|
||||
*.pyc
|
||||
|
@ -25,6 +25,8 @@ fi
|
||||
|
||||
sudo cp -rf $DEVSTACK_PATH/vitrage/vitrage_tempest_tests/tests/resources/static_physical/static_physical_configuration.yaml /etc/vitrage/
|
||||
sudo cp -rf $DEVSTACK_PATH/vitrage/vitrage_tempest_tests/tests/resources/heat/heat_template.yaml /etc/vitrage/
|
||||
sudo cp -rf $DEVSTACK_PATH/vitrage/vitrage_tempest_tests/tests/resources/heat/heat_nested_template.yaml /etc/vitrage/
|
||||
sudo cp -rf $DEVSTACK_PATH/vitrage/vitrage_tempest_tests/tests/resources/heat/server.yaml /etc/vitrage/
|
||||
sudo cp -rf $DEVSTACK_PATH/vitrage/vitrage_tempest_tests/tests/resources/heat/policy.json-tempest /etc/heat/
|
||||
sudo cp $DEVSTACK_PATH/tempest/etc/logging.conf.sample $DEVSTACK_PATH/tempest/etc/logging.conf
|
||||
|
||||
|
@ -79,9 +79,12 @@ class HeatStackDriver(DriverBase):
|
||||
# change transformer that if delete we remove the stack from the graph
|
||||
# and hence all the edges to it
|
||||
|
||||
stack_id = event['stack_identity']
|
||||
if self._is_nested_stack(stack_id):
|
||||
return
|
||||
|
||||
event[DSProps.EVENT_TYPE] = event_type
|
||||
event = HeatStackDriver._retrieve_stack_resources(
|
||||
event, event['stack_identity'])
|
||||
event = HeatStackDriver._retrieve_stack_resources(event, stack_id)
|
||||
|
||||
return HeatStackDriver.make_pickleable(
|
||||
[event],
|
||||
@ -89,6 +92,10 @@ class HeatStackDriver(DriverBase):
|
||||
DatasourceAction.UPDATE,
|
||||
*self.properties_to_filter_out())[0]
|
||||
|
||||
@staticmethod
|
||||
def _is_nested_stack(_id):
|
||||
return HeatStackDriver.client().stacks.get(_id).to_dict()['parent']
|
||||
|
||||
def _filter_resource_types(self):
|
||||
types = self.conf.datasources.types
|
||||
tmp_dict = {}
|
||||
@ -99,8 +106,9 @@ class HeatStackDriver(DriverBase):
|
||||
|
||||
HeatStackDriver.RESOURCE_TYPE = tmp_dict
|
||||
|
||||
def _make_stacks_list(self, stacks):
|
||||
return [stack.__dict__ for stack in stacks]
|
||||
@staticmethod
|
||||
def _make_stacks_list(stacks):
|
||||
return [stack.to_dict() for stack in stacks]
|
||||
|
||||
def _append_stacks_resources(self, stacks):
|
||||
return [self._retrieve_stack_resources(stack, stack['id'])
|
||||
@ -112,9 +120,12 @@ class HeatStackDriver(DriverBase):
|
||||
|
||||
@staticmethod
|
||||
def _retrieve_stack_resources(stack, stack_id):
|
||||
resources = HeatStackDriver.client().resources.list(stack_id)
|
||||
stack['resources'] = [resource.__dict__ for resource in resources
|
||||
if resource.__dict__['resource_type'] in
|
||||
resources = HeatStackDriver.client().resources.list(stack_id,
|
||||
# guess 10 is
|
||||
# enough
|
||||
nested_depth=10)
|
||||
stack['resources'] = [resource.to_dict() for resource in resources
|
||||
if resource.to_dict()['resource_type'] in
|
||||
HeatStackDriver.RESOURCE_TYPE]
|
||||
HeatStackDriver._filter_stack_resources(stack)
|
||||
return stack
|
||||
|
@ -14,6 +14,8 @@
|
||||
|
||||
import time
|
||||
|
||||
from heatclient.common import http
|
||||
from heatclient.common import template_utils
|
||||
from oslo_log import log as logging
|
||||
from vitrage_tempest_tests.tests import utils
|
||||
|
||||
@ -29,8 +31,15 @@ class TestHeatStack(BaseTopologyTest):
|
||||
def setUpClass(cls):
|
||||
super(TestHeatStack, cls).setUpClass()
|
||||
|
||||
@utils.tempest_logger
|
||||
def test_nested_heat_stack(self):
|
||||
self._test_heat_stack(nested=True)
|
||||
|
||||
@utils.tempest_logger
|
||||
def test_heat_stack(self):
|
||||
self._test_heat_stack(nested=False)
|
||||
|
||||
def _test_heat_stack(self, nested):
|
||||
"""heat stack test
|
||||
|
||||
This test validate correctness topology graph with heat stack module
|
||||
@ -38,7 +47,7 @@ class TestHeatStack(BaseTopologyTest):
|
||||
|
||||
try:
|
||||
# Action
|
||||
self._create_stacks(num_stacks=self.NUM_STACKS)
|
||||
self._create_stacks(self.NUM_STACKS, nested)
|
||||
|
||||
# Calculate expected results
|
||||
api_graph = self.vitrage_client.topology.get(all_tenants=True)
|
||||
@ -70,26 +79,33 @@ class TestHeatStack(BaseTopologyTest):
|
||||
finally:
|
||||
self._delete_stacks()
|
||||
|
||||
def _create_stacks(self, num_stacks):
|
||||
with open('/etc/vitrage/heat_template.yaml', 'rb') as f:
|
||||
template_data = f.read()
|
||||
def _create_stacks(self, num_stacks, nested):
|
||||
|
||||
template_file = 'heat_nested_template.yaml'\
|
||||
if nested else 'heat_template.yaml'
|
||||
|
||||
tpl_files, template = template_utils.process_template_path(
|
||||
'/etc/vitrage/' + template_file,
|
||||
object_request=http.authenticated_fetcher(self.heat_client))
|
||||
|
||||
for i in range(num_stacks):
|
||||
self.heat_client.stacks.create(stack_name='stack_%s' % i,
|
||||
template=template_data,
|
||||
stack_name = 'stack_%s' % i + ('_nested' if nested else '')
|
||||
self.heat_client.stacks.create(stack_name=stack_name,
|
||||
template=template,
|
||||
files=tpl_files,
|
||||
parameters={})
|
||||
self._wait_for_status(45,
|
||||
self._check_num_stacks,
|
||||
num_stacks=num_stacks,
|
||||
state='CREATE_COMPLETE')
|
||||
self._wait_for_status(45,
|
||||
self._check_num_stacks,
|
||||
num_stacks=num_stacks,
|
||||
state='CREATE_COMPLETE')
|
||||
|
||||
time.sleep(2)
|
||||
time.sleep(2)
|
||||
|
||||
def _delete_stacks(self):
|
||||
stacks = self.heat_client.stacks.list()
|
||||
for stack in stacks:
|
||||
try:
|
||||
self.heat_client.stacks.delete(stack.__dict__['id'])
|
||||
self.heat_client.stacks.delete(stack.to_dict()['id'])
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@ -97,12 +113,12 @@ class TestHeatStack(BaseTopologyTest):
|
||||
self._check_num_stacks,
|
||||
num_stacks=0)
|
||||
|
||||
time.sleep(2)
|
||||
time.sleep(4)
|
||||
|
||||
def _check_num_stacks(self, num_stacks, state=''):
|
||||
stacks_list = \
|
||||
[stack.__dict__ for stack in self.heat_client.stacks.list()
|
||||
if 'FAILED' not in stack.__dict__['stack_status']]
|
||||
[stack.to_dict() for stack in self.heat_client.stacks.list()
|
||||
if 'FAILED' not in stack.to_dict()['stack_status']]
|
||||
if len(stacks_list) != num_stacks:
|
||||
return False
|
||||
|
||||
|
@ -0,0 +1,12 @@
|
||||
heat_template_version: 2013-05-23
|
||||
|
||||
description: |
|
||||
The heat template is used to demo
|
||||
|
||||
resources:
|
||||
rg:
|
||||
type: OS::Heat::ResourceGroup
|
||||
properties:
|
||||
count: 1
|
||||
resource_def:
|
||||
type: file:///etc/vitrage/server.yaml
|
24
vitrage_tempest_tests/tests/resources/heat/server.yaml
Normal file
24
vitrage_tempest_tests/tests/resources/heat/server.yaml
Normal file
@ -0,0 +1,24 @@
|
||||
heat_template_version: 2013-05-23
|
||||
|
||||
description: |
|
||||
The heat template is used to demo
|
||||
|
||||
parameters:
|
||||
image:
|
||||
type: string
|
||||
default: cirros-0.3.5-x86_64-disk
|
||||
network:
|
||||
type: string
|
||||
default: public
|
||||
flavor:
|
||||
type: string
|
||||
default: m1.small
|
||||
|
||||
resources:
|
||||
server_2:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
image: { get_param: image }
|
||||
flavor: { get_param: flavor }
|
||||
networks:
|
||||
- network: { get_param: network }
|
Loading…
Reference in New Issue
Block a user