From 45073226752c58d640ea5a59b7e532c022a4939b Mon Sep 17 00:00:00 2001
From: Zane Bitter <zbitter@redhat.com>
Date: Mon, 16 Jan 2017 16:58:04 -0500
Subject: [PATCH] Don't load non-referenced resources from DB

During a convergence check operation, we should never load resources from
the database. However, all resources will inevitably be created whenever we
do stack[some_resource]. Previously, resources not represented in the
cached data (i.e. the ones we were least interested in) would get loaded
from the database when this occurred.

This change ensures that only the resource being checked is loaded from the
database, as intended, and adds asserts to prevent any future regression
occurring silently.

Change-Id: I9e568640d776748a1c9f2950f8bb0a8cea325996
Closes-Bug: #1656429
---
 heat/engine/resource.py | 4 ++--
 heat/engine/stack.py    | 5 +++++
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/heat/engine/resource.py b/heat/engine/resource.py
index 46bb98eacc..70aff1deed 100644
--- a/heat/engine/resource.py
+++ b/heat/engine/resource.py
@@ -260,11 +260,11 @@ class Resource(object):
         self.current_template_id = None
         self.root_stack_id = None
 
-        if not stack.has_cache_data(name):
+        if stack.cache_data is None:
             resource = stack.db_resource_get(name)
             if resource:
                 self._load_data(resource)
-        else:
+        elif stack.has_cache_data(name):
             self.action = stack.cache_data[name]['action']
             self.status = stack.cache_data[name]['status']
             self.id = stack.cache_data[name]['id']
diff --git a/heat/engine/stack.py b/heat/engine/stack.py
index cee9ffcc50..4561fb66c8 100644
--- a/heat/engine/stack.py
+++ b/heat/engine/stack.py
@@ -315,6 +315,8 @@ class Stack(collections.Mapping):
     def _find_filtered_resources(self, filters=None):
         rsrc_def_cache = {self.t.id: self.t.resource_definitions(self)}
         if filters:
+            assert self.cache_data is None, \
+                "Resources should not be loaded from the DB"
             resources = resource_objects.Resource.get_all_by_stack(
                 self.context, self.id, filters)
         else:
@@ -354,6 +356,8 @@ class Stack(collections.Mapping):
 
     def _db_resources_get(self):
         if self._db_resources is None:
+            assert self.cache_data is None, \
+                "Resources should not be loaded from the DB"
             _db_resources = resource_objects.Resource.get_all_by_stack(
                 self.context, self.id)
             if not _db_resources:
@@ -1219,6 +1223,7 @@ class Stack(collections.Mapping):
         self.t = template
         self.reset_dependencies()
         self._resources = None
+        self.cache_data = None
 
         if action is not self.CREATE:
             self.updated_time = oslo_timeutils.utcnow()