diff --git a/heat/engine/resources/aws/autoscaling/scaling_policy.py b/heat/engine/resources/aws/autoscaling/scaling_policy.py index b00d4b15ba..2c1dff85ba 100644 --- a/heat/engine/resources/aws/autoscaling/scaling_policy.py +++ b/heat/engine/resources/aws/autoscaling/scaling_policy.py @@ -85,7 +85,8 @@ class AWSScalingPolicy(heat_sp.AutoScalingPolicy): attributes_schema = { ALARM_URL: attributes.Schema( _("A signed url to handle the alarm. (Heat extension)."), - type=attributes.Schema.STRING + type=attributes.Schema.STRING, + cache_mode=attributes.Schema.CACHE_NONE ), } @@ -101,7 +102,7 @@ class AWSScalingPolicy(heat_sp.AutoScalingPolicy): def get_reference_id(self): if self.resource_id is not None: - return six.text_type(self._get_ec2_signed_url()) + return six.text_type(self._get_ec2_signed_url(never_expire=True)) else: return six.text_type(self.name) diff --git a/heat/engine/resources/openstack/heat/scaling_policy.py b/heat/engine/resources/openstack/heat/scaling_policy.py index c0afc212e4..e1f3c52f96 100644 --- a/heat/engine/resources/openstack/heat/scaling_policy.py +++ b/heat/engine/resources/openstack/heat/scaling_policy.py @@ -99,7 +99,8 @@ class AutoScalingPolicy(signal_responder.SignalResponder): attributes_schema = { ALARM_URL: attributes.Schema( _("A signed url to handle the alarm."), - type=attributes.Schema.STRING + type=attributes.Schema.STRING, + cache_mode=attributes.Schema.CACHE_NONE ), SIGNAL_URL: attributes.Schema( _("A url to handle the alarm using native API."), @@ -186,7 +187,7 @@ class AutoScalingPolicy(signal_responder.SignalResponder): if self.resource_id is None: return if name == self.ALARM_URL: - return six.text_type(self._get_ec2_signed_url()) + return six.text_type(self._get_ec2_signed_url(never_expire=True)) elif name == self.SIGNAL_URL: return six.text_type(self._get_heat_signal_url()) diff --git a/heat/engine/resources/openstack/mistral/workflow.py b/heat/engine/resources/openstack/mistral/workflow.py index 8794b23d72..9dfb0d86d6 100644 --- a/heat/engine/resources/openstack/mistral/workflow.py +++ b/heat/engine/resources/openstack/mistral/workflow.py @@ -376,7 +376,8 @@ class Workflow(signal_responder.SignalResponder, ALARM_URL: attributes.Schema( _("A signed url to create executions for workflows specified in " "Workflow resource."), - type=attributes.Schema.STRING + type=attributes.Schema.STRING, + cache_mode=attributes.Schema.CACHE_NONE ), EXECUTIONS: attributes.Schema( _("List of workflows' executions, each of them is a dictionary " @@ -661,7 +662,7 @@ class Workflow(signal_responder.SignalResponder, self.INPUT: self.properties.get(self.INPUT)} elif name == self.ALARM_URL and self.resource_id is not None: - return six.text_type(self._get_ec2_signed_url()) + return six.text_type(self._get_ec2_signed_url(never_expire=True)) def resource_mapping(): diff --git a/heat/engine/resources/openstack/sahara/job.py b/heat/engine/resources/openstack/sahara/job.py index 711ee49434..96e51df9f4 100644 --- a/heat/engine/resources/openstack/sahara/job.py +++ b/heat/engine/resources/openstack/sahara/job.py @@ -182,7 +182,8 @@ class SaharaJob(signal_responder.SignalResponder, resource.Resource): DEFAULT_EXECUTION_URL: attributes.Schema( _("A signed url to create execution specified in " "default_execution_data property."), - type=attributes.Schema.STRING + type=attributes.Schema.STRING, + cache_mode=attributes.Schema.CACHE_NONE ), EXECUTIONS: attributes.Schema( _("List of the job executions."), @@ -298,7 +299,7 @@ class SaharaJob(signal_responder.SignalResponder, resource.Resource): def _resolve_attribute(self, name): if name == self.DEFAULT_EXECUTION_URL: - return six.text_type(self._get_ec2_signed_url()) + return six.text_type(self._get_ec2_signed_url(never_expire=True)) elif name == self.EXECUTIONS: try: job_execs = self.client().job_executions.find( diff --git a/heat/engine/resources/signal_responder.py b/heat/engine/resources/signal_responder.py index 3fffc88ef9..7adcbf76d3 100644 --- a/heat/engine/resources/signal_responder.py +++ b/heat/engine/resources/signal_responder.py @@ -114,7 +114,8 @@ class SignalResponder(stack_user.StackUser): 'region_name': (self.context.region_name or cfg.CONF.region_name_for_services)} - def _get_ec2_signed_url(self, signal_type=SIGNAL): + def _get_ec2_signed_url(self, signal_type=SIGNAL, + never_expire=False): """Create properly formatted and pre-signed URL. This uses the created user for the credentials. @@ -158,15 +159,16 @@ class SignalResponder(stack_user.StackUser): # need to calculate the signature with the path component unquoted, but # ensure the actual URL contains the quoted version... unquoted_path = urlparse.unquote(host_url.path + path) + params = {'SignatureMethod': 'HmacSHA256', + 'SignatureVersion': '2', + 'AWSAccessKeyId': access_key} + if not never_expire: + params['Timestamp'] = timeutils.utcnow().strftime( + "%Y-%m-%dT%H:%M:%SZ") request = {'host': host_url.netloc.lower(), 'verb': SIGNAL_VERB[signal_type], 'path': unquoted_path, - 'params': {'SignatureMethod': 'HmacSHA256', - 'SignatureVersion': '2', - 'AWSAccessKeyId': access_key, - 'Timestamp': - timeutils.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ") - }} + 'params': params} # Sign the request signer = ec2_utils.Ec2Signer(secret_key) request['params']['Signature'] = signer.generate(request) diff --git a/heat/tests/autoscaling/test_heat_scaling_policy.py b/heat/tests/autoscaling/test_heat_scaling_policy.py index 1ff7339264..8af526ecef 100644 --- a/heat/tests/autoscaling/test_heat_scaling_policy.py +++ b/heat/tests/autoscaling/test_heat_scaling_policy.py @@ -183,7 +183,6 @@ class ScalingPolicyAttrTest(common.HeatTestCase): self.assertEqual('Signature', args[1].split('=')[0]) self.assertEqual('SignatureMethod', args[2].split('=')[0]) self.assertEqual('SignatureVersion', args[3].split('=')[0]) - self.assertEqual('Timestamp', args[4].split('=')[0]) def test_signal_attribute(self): heat_plugin = self.stack.clients.client_plugin('heat')