]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Make the waitcondition signed url more generic
authorAngus Salkeld <asalkeld@redhat.com>
Thu, 4 Jul 2013 03:14:42 +0000 (13:14 +1000)
committerAngus Salkeld <asalkeld@redhat.com>
Sun, 7 Jul 2013 23:08:40 +0000 (09:08 +1000)
This will be used in a later patch, for alarms as well.

blueprint watch-ceilometer
Change-Id: I4b3a6be0effb975ddd8214741cfca6f40c493dbe

heat/engine/resources/wait_condition.py
heat/engine/signal_responder.py [new file with mode: 0644]

index 035a69b7295ce2b3d637ded7a794efbb4d2cd7b1..097097dd4f605b3c784a2471053e1484dda87229 100644 (file)
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import urllib
-import urlparse
 import json
 
-from oslo.config import cfg
-
-from keystoneclient.contrib.ec2.utils import Ec2Signer
-
 from heat.common import exception
 from heat.common import identifier
 from heat.engine import resource
 from heat.engine import scheduler
+from heat.engine import signal_responder
 
 from heat.openstack.common import log as logging
 
 logger = logging.getLogger(__name__)
 
 
-class WaitConditionHandle(resource.Resource):
+class WaitConditionHandle(signal_responder.SignalResponder):
     '''
     the main point of this class is to :
     have no dependancies (so the instance can reference it)
@@ -41,62 +36,13 @@ class WaitConditionHandle(resource.Resource):
     '''
     properties_schema = {}
 
-    def _sign_url(self, credentials, path):
-        """
-        Create properly formatted and pre-signed URL using supplied credentials
-        See http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/
-            rest-signature.html
-        Also see boto/auth.py::QuerySignatureV2AuthHandler
-        """
-        host_url = urlparse.urlparse(cfg.CONF.heat_waitcondition_server_url)
-        # Note the WSGI spec apparently means that the webob request we end up
-        # prcessing in the CFN API (ec2token.py) has an unquoted path, so we
-        # need to calculate the signature with the path component unquoted, but
-        # ensure the actual URL contains the quoted version...
-        unquoted_path = urllib.unquote(host_url.path + path)
-        request = {'host': host_url.netloc.lower(),
-                   'verb': 'PUT',
-                   'path': unquoted_path,
-                   'params': {'SignatureMethod': 'HmacSHA256',
-                              'SignatureVersion': '2',
-                              'AWSAccessKeyId': credentials.access,
-                              'Timestamp':
-                              self.created_time.strftime("%Y-%m-%dT%H:%M:%SZ")
-                              }}
-        # Sign the request
-        signer = Ec2Signer(credentials.secret)
-        request['params']['Signature'] = signer.generate(request)
-
-        qs = urllib.urlencode(request['params'])
-        url = "%s%s?%s" % (cfg.CONF.heat_waitcondition_server_url.lower(),
-                           path, qs)
-        return url
-
-    def handle_create(self):
-        # Create a keystone user so we can create a signed URL via FnGetRefId
-        user_id = self.keystone().create_stack_user(
-            self.physical_resource_name())
-        kp = self.keystone().get_ec2_keypair(user_id)
-        if not kp:
-            raise exception.Error("Error creating ec2 keypair for user %s" %
-                                  user_id)
-        else:
-            self.resource_id_set(user_id)
-
-    def handle_delete(self):
-        if self.resource_id is None:
-            return
-        self.keystone().delete_stack_user(self.resource_id)
-
     def FnGetRefId(self):
         '''
         Override the default resource FnGetRefId so we return the signed URL
         '''
         if self.resource_id:
-            urlpath = self.identifier().arn_url_path()
-            ec2_creds = self.keystone().get_ec2_keypair(self.resource_id)
-            signed_url = self._sign_url(ec2_creds, urlpath)
-            return unicode(signed_url)
+            wc = signal_responder.WAITCONDITION
+            return unicode(self._get_signed_url(signal_type=wc))
         else:
             return unicode(self.name)
 
diff --git a/heat/engine/signal_responder.py b/heat/engine/signal_responder.py
new file mode 100644 (file)
index 0000000..10a2845
--- /dev/null
@@ -0,0 +1,93 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import urllib
+import urlparse
+
+from oslo.config import cfg
+
+from keystoneclient.contrib.ec2 import utils as ec2_utils
+
+from heat.common import exception
+from heat.engine import resource
+
+from heat.openstack.common import log
+
+LOG = log.getLogger(__name__)
+SIGNAL_TYPES = (
+    WAITCONDITION, SIGNAL
+) = (
+    '/waitcondition', '/signal'
+)
+
+
+class SignalResponder(resource.Resource):
+
+    def handle_create(self):
+        # Create a keystone user so we can create a signed URL via FnGetRefId
+        user_id = self.keystone().create_stack_user(
+            self.physical_resource_name())
+        kp = self.keystone().get_ec2_keypair(user_id)
+        if not kp:
+            raise exception.Error("Error creating ec2 keypair for user %s" %
+                                  user_id)
+        else:
+            self.resource_id_set(user_id)
+
+    def handle_delete(self):
+        if self.resource_id is None:
+            return
+        self.keystone().delete_stack_user(self.resource_id)
+
+    def _get_signed_url(self, signal_type=SIGNAL):
+        """Create properly formatted and pre-signed URL.
+
+        This uses the created user for the credentials.
+
+        See http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/
+        restarter-signature.html
+        Also see boto/auth.py::QuerySignatureV2AuthHandler
+
+        :param signal_type: either WAITCONDITION or SIGNAL.
+        """
+        waitcond_url = cfg.CONF.heat_waitcondition_server_url
+        signal_url = waitcond_url.replace('/waitcondition', signal_type)
+        host_url = urlparse.urlparse(signal_url)
+
+        path = self.identifier().arn_url_path()
+        credentials = self.keystone().get_ec2_keypair(self.resource_id)
+
+        # Note the WSGI spec apparently means that the webob request we end up
+        # prcessing in the CFN API (ec2token.py) has an unquoted path, so we
+        # need to calculate the signature with the path component unquoted, but
+        # ensure the actual URL contains the quoted version...
+        unquoted_path = urllib.unquote(host_url.path + path)
+        request = {'host': host_url.netloc.lower(),
+                   'verb': 'PUT',
+                   'path': unquoted_path,
+                   'params': {'SignatureMethod': 'HmacSHA256',
+                              'SignatureVersion': '2',
+                              'AWSAccessKeyId': credentials.access,
+                              'Timestamp':
+                              self.created_time.strftime("%Y-%m-%dT%H:%M:%SZ")
+                              }}
+        # Sign the requested
+        signer = ec2_utils.Ec2Signer(credentials.secret)
+        request['params']['Signature'] = signer.generate(request)
+
+        qs = urllib.urlencode(request['params'])
+        url = "%s%s?%s" % (signal_url.lower(),
+                           path, qs)
+        return url