summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRabi Mishra <ramishra@redhat.com>2020-06-03 18:18:23 +0530
committerRabi Mishra <ramishra@redhat.com>2020-07-29 11:50:56 +0000
commitc2fa4e0f30876e709d4cf515349b64287191fb38 (patch)
tree7b40c048db6558041f8142af99a78cf93217c9c7
parent5386d51040fede7d5a60fd34a7fbf4c39984f152 (diff)
downloadheat-c2fa4e0f30876e709d4cf515349b64287191fb38.tar.gz
Don't store signal_url for ec2 signaling of deployments
As part of a CVE keystone has started checking[1] the timestamp of signed ec2 token with default TTL of 15 mins. We can't store the ec2 url anymore for future use for those. This moves the caching logic to BaseWaitConditionHandle class. Conflicts: heat/engine/resources/signal_responder.py heat/tests/test_signal.py [1] https://review.opendev.org/#/c/724124/ Change-Id: I6b74faed820caccd39210bd48a212b2dedca46b9 Task: 39985 Related-Bug: #1872737 (cherry picked from commit 3047ca7d36baaa59ab2960602da956d2087a2a62) (cherry picked from commit 913c428b3030c67b3110af75f24dd8f99be00dbf)
-rw-r--r--heat/engine/resources/signal_responder.py8
-rw-r--r--heat/engine/resources/wait_condition.py9
-rw-r--r--heat/tests/aws/test_waitcondition.py5
-rw-r--r--heat/tests/engine/service/test_stack_resources.py5
-rw-r--r--heat/tests/test_metadata_refresh.py5
-rw-r--r--heat/tests/test_signal.py7
6 files changed, 27 insertions, 12 deletions
diff --git a/heat/engine/resources/signal_responder.py b/heat/engine/resources/signal_responder.py
index 23c1f9c76..2d61d51f3 100644
--- a/heat/engine/resources/signal_responder.py
+++ b/heat/engine/resources/signal_responder.py
@@ -15,6 +15,7 @@ from keystoneclient.contrib.ec2 import utils as ec2_utils
from oslo_config import cfg
from oslo_log import log as logging
from oslo_serialization import jsonutils
+from oslo_utils import timeutils
from six.moves.urllib import parse as urlparse
from heat.common import exception
@@ -121,10 +122,6 @@ class SignalResponder(stack_user.StackUser):
:param signal_type: either WAITCONDITION or SIGNAL.
"""
- stored = self.data().get('ec2_signed_url')
- if stored is not None:
- return stored
-
access_key = self.data().get('access_key')
secret_key = self.data().get('secret_key')
@@ -167,7 +164,7 @@ class SignalResponder(stack_user.StackUser):
'SignatureVersion': '2',
'AWSAccessKeyId': access_key,
'Timestamp':
- self.created_time.strftime("%Y-%m-%dT%H:%M:%SZ")
+ timeutils.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")
}}
# Sign the request
signer = ec2_utils.Ec2Signer(secret_key)
@@ -177,7 +174,6 @@ class SignalResponder(stack_user.StackUser):
url = "%s%s?%s" % (signal_url.lower(),
path, qs)
- self.data_set('ec2_signed_url', url)
return url
def _delete_ec2_signed_url(self):
diff --git a/heat/engine/resources/wait_condition.py b/heat/engine/resources/wait_condition.py
index 87d797237..4fd25b899 100644
--- a/heat/engine/resources/wait_condition.py
+++ b/heat/engine/resources/wait_condition.py
@@ -41,6 +41,15 @@ class BaseWaitConditionHandle(signal_responder.SignalResponder):
'SUCCESS',
)
+ def _get_ec2_signed_url(self, signal_type=signal_responder.WAITCONDITION):
+ stored = self.data().get('ec2_signed_url')
+ if stored is not None:
+ return stored
+ url = super(BaseWaitConditionHandle,
+ self)._get_ec2_signed_url(signal_type)
+ self.data_set('ec2_signed_url', url)
+ return url
+
def handle_create(self):
super(BaseWaitConditionHandle, self).handle_create()
self.resource_id_set(self._get_user_id())
diff --git a/heat/tests/aws/test_waitcondition.py b/heat/tests/aws/test_waitcondition.py
index 2353469e7..ebd9df5fc 100644
--- a/heat/tests/aws/test_waitcondition.py
+++ b/heat/tests/aws/test_waitcondition.py
@@ -375,7 +375,9 @@ class WaitConditionHandleTest(common.HeatTestCase):
def test_handle(self):
stack_id = 'STACKABCD1234'
stack_name = 'test_stack2'
- created_time = datetime.datetime(2012, 11, 29, 13, 49, 37)
+ now = datetime.datetime(2012, 11, 29, 13, 49, 37)
+ timeutils.set_time_override(now)
+ self.addCleanup(timeutils.clear_time_override)
self.stack = self.create_stack(stack_id=stack_id,
stack_name=stack_name)
@@ -387,7 +389,6 @@ class WaitConditionHandleTest(common.HeatTestCase):
# clear the url
rsrc.data_set('ec2_signed_url', None, False)
- rsrc.created_time = created_time
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
connection_url = "".join([
'http://server.test:8000/v1/waitcondition/',
diff --git a/heat/tests/engine/service/test_stack_resources.py b/heat/tests/engine/service/test_stack_resources.py
index cea0923e3..efd775e42 100644
--- a/heat/tests/engine/service/test_stack_resources.py
+++ b/heat/tests/engine/service/test_stack_resources.py
@@ -17,6 +17,7 @@ import six
from heat.common import exception
from heat.common import identifier
+from heat.engine.clients.os import heat_plugin
from heat.engine.clients.os import keystone
from heat.engine.clients.os.keystone import fake_keystoneclient as fake_ks
from heat.engine import dependencies
@@ -451,11 +452,13 @@ class StackResourcesServiceTest(common.HeatTestCase):
self.assertEqual(exception.InvalidBreakPointHook,
ex.exc_info[0])
+ @mock.patch.object(heat_plugin.HeatClientPlugin, 'get_heat_cfn_url')
@mock.patch.object(res.Resource, 'metadata_update')
@mock.patch.object(res.Resource, 'signal')
@mock.patch.object(service.EngineService, '_get_stack')
def test_signal_calls_metadata_update(self, mock_get, mock_signal,
- mock_update):
+ mock_update, mock_get_cfn):
+ mock_get_cfn.return_value = 'http://server.test:8000/v1'
# fake keystone client
self.patchobject(keystone.KeystoneClientPlugin, '_create',
return_value=fake_ks.FakeKeystoneClient())
diff --git a/heat/tests/test_metadata_refresh.py b/heat/tests/test_metadata_refresh.py
index b638f3d36..59310a893 100644
--- a/heat/tests/test_metadata_refresh.py
+++ b/heat/tests/test_metadata_refresh.py
@@ -16,6 +16,7 @@ from oslo_serialization import jsonutils
from heat.common import identifier
from heat.common import template_format
from heat.engine.clients.os import glance
+from heat.engine.clients.os import heat_plugin
from heat.engine.clients.os import nova
from heat.engine import environment
from heat.engine.resources.aws.cfn.wait_condition_handle import (
@@ -222,14 +223,16 @@ class WaitConditionMetadataUpdateTest(common.HeatTestCase):
@mock.patch.object(nova.NovaClientPlugin, 'find_flavor_by_name_or_id')
@mock.patch.object(glance.GlanceClientPlugin, 'find_image_by_name_or_id')
+ @mock.patch.object(heat_plugin.HeatClientPlugin, 'get_heat_cfn_url')
@mock.patch.object(instance.Instance, 'handle_create')
@mock.patch.object(instance.Instance, 'check_create_complete')
@mock.patch.object(scheduler.TaskRunner, '_sleep')
@mock.patch.object(WaitConditionHandle, 'identifier')
def test_wait_metadata(self, mock_identifier, mock_sleep,
- mock_check, mock_handle, *args):
+ mock_check, mock_handle, mock_get, *args):
"""Tests a wait condition metadata update after a signal call."""
+ mock_get.return_value = 'http://server.test:8000/v1'
# Setup Stack
temp = template_format.parse(TEST_TEMPLATE_WAIT_CONDITION)
template = tmpl.Template(temp)
diff --git a/heat/tests/test_signal.py b/heat/tests/test_signal.py
index 87e54c9b7..4d1e58c1c 100644
--- a/heat/tests/test_signal.py
+++ b/heat/tests/test_signal.py
@@ -15,6 +15,7 @@ import datetime
from keystoneauth1 import exceptions as kc_exceptions
import mock
+from oslo_utils import timeutils
import six
from six.moves.urllib import parse as urlparse
@@ -151,6 +152,10 @@ class SignalTest(common.HeatTestCase):
@mock.patch.object(heat_plugin.HeatClientPlugin, 'get_heat_cfn_url')
def test_FnGetAtt_alarm_url(self, mock_get):
+ now = datetime.datetime(2012, 11, 29, 13, 49, 37)
+ timeutils.set_time_override(now)
+ self.addCleanup(timeutils.clear_time_override)
+
# Setup
stack_id = stack_name = 'FnGetAtt-alarm-url'
stack = self._create_stack(TEMPLATE_CFN_SIGNAL,
@@ -160,8 +165,6 @@ class SignalTest(common.HeatTestCase):
mock_get.return_value = 'http://server.test:8000/v1'
rsrc = stack['signal_handler']
- created_time = datetime.datetime(2012, 11, 29, 13, 49, 37)
- rsrc.created_time = created_time
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)