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 commit3047ca7d36
) (cherry picked from commit913c428b30
)
This commit is contained in:
parent
5386d51040
commit
c2fa4e0f30
|
@ -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):
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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/',
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue