Hello community,

here is the log from the commit of package openstack-heat for openSUSE:Factory 
checked in at 2013-06-20 21:25:09
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/openstack-heat (Old)
 and      /work/SRC/openSUSE:Factory/.openstack-heat.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "openstack-heat"

Changes:
--------
--- /work/SRC/openSUSE:Factory/openstack-heat/openstack-heat.changes    
2013-04-29 14:09:36.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.openstack-heat.new/openstack-heat.changes       
2013-06-20 21:25:10.000000000 +0200
@@ -0,0 +1,39 @@
+--------------------------------------------------------------------
+Fri Jun 14 00:11:36 UTC 2013 - [email protected]
+
+- Update to version 2013.1.3.a2.g1689425:
+  + heat api : Update ec2token middleware for v4 signatures
+
+-------------------------------------------------------------------
+Thu Jun 13 22:03:32 UTC 2013 - [email protected]
+
+- fix init script 
+
+--------------------------------------------------------------------
+Fri Jun  7 23:49:53 UTC 2013 - [email protected]
+
+- Update to version 2013.1.3.a1.g21d342a:
+  + Bump stable/grizzly next version to 2013.1.3
+
+--------------------------------------------------------------------
+Thu May 30 23:59:37 UTC 2013 - [email protected]
+
+- Update to version 2013.1.1.a4.g3dbe9f4:
+  + heat-cfn: Handle parameters with = in them
+  + uses os.urandom instead of Crypto.Random for backward compatibility
+
+-------------------------------------------------------------------
+Wed May 29 10:43:21 UTC 2013 - [email protected]
+
+- remove setBadness call from rpmlintrc 
+
+-------------------------------------------------------------------
+Mon May 27 21:38:10 UTC 2013 - [email protected]
+
+- update requires for test subpackage 
+
+-------------------------------------------------------------------
+Sat May 18 13:32:20 UTC 2013 - [email protected]
+
+- update heat-requires based on pip-requires 
+

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ openstack-heat-doc.spec ++++++
--- /var/tmp/diff_new_pack.jaDiCW/_old  2013-06-20 21:25:11.000000000 +0200
+++ /var/tmp/diff_new_pack.jaDiCW/_new  2013-06-20 21:25:11.000000000 +0200
@@ -19,7 +19,7 @@
 %define component heat
 
 Name:           openstack-%{component}-doc
-Version:        2013.1
+Version:        2013.1.3.a2.g1689425
 Release:        0
 Summary:        OpenStack Orchestration (Heat) - Documentation
 License:        Apache-2.0
@@ -60,7 +60,7 @@
 This package contains documentation files for openstack-heat.
 
 %prep
-%setup -q -n heat-2013.1
+%setup -q -n heat-2013.1.3.a2.g1689425
 %openstack_cleanup_prep
 
 %build

++++++ openstack-heat.spec ++++++
--- /var/tmp/diff_new_pack.jaDiCW/_old  2013-06-20 21:25:11.000000000 +0200
+++ /var/tmp/diff_new_pack.jaDiCW/_new  2013-06-20 21:25:11.000000000 +0200
@@ -21,7 +21,7 @@
 %define username openstack-%{component}
 
 Name:           openstack-%{component}
-Version:        2013.1
+Version:        2013.1.3.a2.g1689425
 Release:        0
 Summary:        Openstack Orchestration (Heat)
 License:        Apache-2.0
@@ -60,28 +60,29 @@
 Summary:        Openstack Orchestration (Heat) - Python module
 Group:          Development/Languages/Python
 Requires:       python >= 2.6.8
-Requires:       python-PasteDeploy = 1.5.0
+Requires:       python-PasteDeploy >= 1.5.0
 Requires:       python-PyYAML >= 3.1.0
-Requires:       python-Routes
-Requires:       python-Routes
+Requires:       python-Routes >= 1.12.3
+Requires:       python-Routes >= 1.12.3
 Requires:       python-SQLAlchemy >= 0.7.8
-Requires:       python-WebOb
+Requires:       python-WebOb >= 1.2.3
 Requires:       python-argparse
 Requires:       python-boto >= 2.4.0
 Requires:       python-cinderclient
-Requires:       python-eventlet >= 0.9.17
+Requires:       python-eventlet >= 0.12.0
 Requires:       python-glanceclient
-Requires:       python-greenlet >= 0.3.1
+Requires:       python-greenlet >= 0.3.2
 Requires:       python-httplib2
 Requires:       python-iso8601 >= 0.1.4
 Requires:       python-keystoneclient
 Requires:       python-kombu >= 1.0.4
 Requires:       python-lxml >= 2.3
-Requires:       python-memcached
 Requires:       python-novaclient
 Requires:       python-oslo.config >= 1.1.0
 Requires:       python-pycrypto >= 2.1.0
-Requires:       python-quantumclient
+Requires:       python-python-memcached
+Requires:       python-quantumclient >= 2.2.0
+Requires:       python-sqlalchemy >= 0.7.8
 Requires:       python-sqlalchemy-migrate >= 0.7.2
 Requires:       python-swiftclient
 
@@ -127,18 +128,19 @@
 Requires:       openstack-%{component}-api-cloudwatch
 Requires:       python-coverage
 Requires:       python-glanceclient
-Requires:       python-mox == 0.5.3
+Requires:       python-mox >= 0.5.3
 Requires:       python-nose
 Requires:       python-nosexcover
 Requires:       python-openstack.nose_plugin >= 0.7
 Requires:       python-paramiko
-Requires:       python-pep8
+Requires:       python-pep8 >= 1.3.4
+Requires:       python-pyflakes
 
 %description test
 This package contains testsuite files for %{name}.
 
 %prep
-%setup -q -n heat-2013.1
+%setup -q -n heat-2013.1.3.a2.g1689425
 %openstack_cleanup_prep
 #NOTE(saschpe): This test checks executables in heat module dir, makes no 
sense:
 sed -i "s|basepath = .*|basepath = \"%{_prefix}\"|" heat/tests/test_cli.py

++++++ heat-stable-grizzly.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/heat-2013.1/.gitreview 
new/heat-2013.1.3.a2.g1689425/.gitreview
--- old/heat-2013.1/.gitreview  2013-04-04 18:19:10.000000000 +0200
+++ new/heat-2013.1.3.a2.g1689425/.gitreview    2013-06-13 22:23:25.000000000 
+0200
@@ -2,3 +2,4 @@
 host=review.openstack.org
 port=29418
 project=openstack/heat.git
+defaultbranch=stable/grizzly
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/heat-2013.1/AUTHORS 
new/heat-2013.1.3.a2.g1689425/AUTHORS
--- old/heat-2013.1/AUTHORS     2013-04-04 18:20:38.000000000 +0200
+++ new/heat-2013.1.3.a2.g1689425/AUTHORS       2013-06-13 22:25:35.000000000 
+0200
@@ -1,10 +1,12 @@
 Aaron Rosen <[email protected]>
+Adam Gandelman <[email protected]>
 Andrew Hutchings <[email protected]>
 Angus Salkeld <[email protected]>
 Chris Alfonso <[email protected]>
 Clint Byrum <[email protected]>
 Dirk Mueller <[email protected]>
 Eoghan Glynn <[email protected]>
+Giulio Fidente <[email protected]>
 Greg Blomquist <[email protected]>
 Ian Main <[email protected]>
 Jeff Peeler <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/heat-2013.1/ChangeLog 
new/heat-2013.1.3.a2.g1689425/ChangeLog
--- old/heat-2013.1/ChangeLog   2013-04-04 18:20:38.000000000 +0200
+++ new/heat-2013.1.3.a2.g1689425/ChangeLog     2013-06-13 22:25:35.000000000 
+0200
@@ -1,3 +1,85 @@
+commit 16894252caaace4c3daede236efa42466e34cd09
+Author: Steven Hardy <[email protected]>
+Date:   Mon Apr 8 14:53:04 2013 +0100
+
+    heat api : Update ec2token middleware for v4 signatures
+    
+    Update ec2token so it can verify v4 signature formats.
+    
+    Note for v4 signatures to work you need keystone to be using
+    python-keystoneclient >= 0.2.4, or contain the patch from
+    https://review.openstack.org/#/c/26013/
+    
+    This change is backwards compatible, as older keystoneclient
+    versions will simply ignore the additional request keys
+    
+    fixes bug #1122472
+    
+    Change-Id: Iccc6be7913ab5ca5813a2e0c8f66cda0ccd85a0b
+
+ heat/api/aws/ec2token.py        |   61 ++++++--
+ heat/tests/test_api_ec2token.py |  315 +++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 366 insertions(+), 10 deletions(-)
+
+commit 21d342a684132e413a0e4a453caca17aab73fb73
+Author: Adam Gandelman <[email protected]>
+Date:   Thu Jun 6 12:07:53 2013 -0700
+
+    Bump stable/grizzly next version to 2013.1.3
+    
+    Change-Id: Id5f00df4039b83b26d2ec0a2aaff8a5c16510b72
+
+ setup.py |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3dbe9f424c0ba885a4dae5afdd8cb91efa555358
+Merge: 2d81dc9 d74b142
+Author: Jenkins <[email protected]>
+Date:   Thu May 30 21:53:50 2013 +0000
+
+    Merge "uses os.urandom instead of Crypto.Random for backward 
compatibility" into stable/grizzly
+
+commit d74b1420a3ce427647a684f78e650c73db2be767
+Author: Giulio Fidente <[email protected]>
+Date:   Thu Apr 11 17:31:53 2013 +0200
+
+    uses os.urandom instead of Crypto.Random for backward compatibility
+    
+    Crypto.Random has been introduced by pycrypto 2.1 but in RHEL6 and
+    derivates you will only find pycrypto 2.0.1
+    
+    bug #1186022
+    
+    Change-Id: Ib601981b0b8fcb5b3e8fc8761ee05adf7f6574fa
+
+ heat/common/crypt.py |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 2d81dc9baad2459211d3493dcb91ab70de26aaf2
+Author: Zane Bitter <[email protected]>
+Date:   Thu Apr 11 20:08:24 2013 +0200
+
+    heat-cfn: Handle parameters with = in them
+    
+    Change-Id: Iee193169ec3dd583158ad929df20541ec210149b
+
+ heat/cfn_client/client.py |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6ed78c24514df7de994a80f6c0c16721735b86dc
+Author: Thierry Carrez <[email protected]>
+Date:   Thu Apr 4 18:20:38 2013 +0200
+
+    Open stable/grizzly
+    
+    Bump "next" version to 2013.1.1 and switch default branch in .gitreview.
+    
+    Change-Id: Ie272a3360871e61626e2129f47415f8cf251fef2
+
+ .gitreview |    1 +
+ setup.py   |    2 +-
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
 commit e72608459424869a36c109637a159a49866557a9
 Author: Steve Baker <[email protected]>
 Date:   Wed Mar 27 13:35:54 2013 +1300
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/heat-2013.1/PKG-INFO 
new/heat-2013.1.3.a2.g1689425/PKG-INFO
--- old/heat-2013.1/PKG-INFO    2013-04-04 18:20:38.000000000 +0200
+++ new/heat-2013.1.3.a2.g1689425/PKG-INFO      2013-06-13 22:25:39.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: heat
-Version: 2013.1
+Version: 2013.1.3.a2.g1689425
 Summary: The heat project provides services for provisioning virtual machines
 Home-page: http://heat.openstack.org/
 Author: Heat API Developers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/heat-2013.1/heat/api/aws/ec2token.py 
new/heat-2013.1.3.a2.g1689425/heat/api/aws/ec2token.py
--- old/heat-2013.1/heat/api/aws/ec2token.py    2013-04-04 18:19:11.000000000 
+0200
+++ new/heat-2013.1.3.a2.g1689425/heat/api/aws/ec2token.py      2013-06-13 
22:23:25.000000000 +0200
@@ -16,6 +16,7 @@
 import urlparse
 import httplib
 import gettext
+import hashlib
 
 gettext.install('heat', unicode=1)
 
@@ -37,6 +38,43 @@
         self.conf = conf
         self.application = app
 
+    def _get_signature(self, req):
+        """
+        Extract the signature from the request, this can be a get/post
+        variable or for v4 also in a header called 'Authorization'
+        - params['Signature'] == version 0,1,2,3
+        - params['X-Amz-Signature'] == version 4
+        - header 'Authorization' == version 4
+        see http://docs.aws.amazon.com/general/latest/gr/
+            sigv4-signed-request-examples.html
+        """
+        sig = req.params.get('Signature') or req.params.get('X-Amz-Signature')
+        if sig is None and 'Authorization' in req.headers:
+            auth_str = req.headers['Authorization']
+            sig = auth_str.partition("Signature=")[2].split(',')[0]
+
+        return sig
+
+    def _get_access(self, req):
+        """
+        Extract the access key identifier, for v 0/1/2/3 this is passed
+        as the AccessKeyId parameter, for version4 it is either and
+        X-Amz-Credential parameter or a Credential= field in the
+        'Authorization' header string
+        """
+        access = req.params.get('AWSAccessKeyId')
+        if access is None:
+            cred_param = req.params.get('X-Amz-Credential')
+            if cred_param:
+                access = cred_param.split("/")[0]
+
+        if access is None and 'Authorization' in req.headers:
+            auth_str = req.headers['Authorization']
+            cred_str = auth_str.partition("Credential=")[2].split(',')[0]
+            access = cred_str.split("/")[0]
+
+        return access
+
     @webob.dec.wsgify(RequestClass=wsgi.Request)
     def __call__(self, req):
         # Read request signature and access id.
@@ -45,37 +83,40 @@
         # Returning here just means the user didn't supply AWS
         # authentication and we'll let the app try native keystone next.
         logger.info("Checking AWS credentials..")
-        try:
-            signature = req.params['Signature']
-        except KeyError:
-            logger.info("No AWS Signature found.")
+
+        signature = self._get_signature(req)
+        if not signature:
             if 'X-Auth-User' in req.headers:
                 return self.application
             else:
+                logger.info("No AWS Signature found.")
                 raise exception.HeatIncompleteSignatureError()
 
-        try:
-            access = req.params['AWSAccessKeyId']
-        except KeyError:
-            logger.info("No AWSAccessKeyId found.")
+        access = self._get_access(req)
+        if not access:
             if 'X-Auth-User' in req.headers:
                 return self.application
             else:
+                logger.info("No AWSAccessKeyId/Authorization Credential")
                 raise exception.HeatMissingAuthenticationTokenError()
 
         logger.info("AWS credentials found, checking against keystone.")
         # Make a copy of args for authentication and signature verification.
         auth_params = dict(req.params)
-        # Not part of authentication args
-        auth_params.pop('Signature')
+        # 'Signature' param Not part of authentication args
+        auth_params.pop('Signature', None)
 
         # Authenticate the request.
+        # AWS v4 authentication requires a hash of the body
+        body_hash = hashlib.sha256(req.body).hexdigest()
         creds = {'ec2Credentials': {'access': access,
                                     'signature': signature,
                                     'host': req.host,
                                     'verb': req.method,
                                     'path': req.path,
                                     'params': auth_params,
+                                    'headers': req.headers,
+                                    'body_hash': body_hash
                                     }}
         creds_json = None
         try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/heat-2013.1/heat/cfn_client/client.py 
new/heat-2013.1.3.a2.g1689425/heat/cfn_client/client.py
--- old/heat-2013.1/heat/cfn_client/client.py   2013-04-04 18:19:11.000000000 
+0200
+++ new/heat-2013.1.3.a2.g1689425/heat/cfn_client/client.py     2013-06-13 
22:23:25.000000000 +0200
@@ -137,7 +137,7 @@
         parameters = {}
         if options.parameters:
             for count, p in enumerate(options.parameters.split(';'), 1):
-                (n, v) = p.split('=')
+                (n, v) = p.split('=', 1)
                 parameters['Parameters.member.%d.ParameterKey' % count] = n
                 parameters['Parameters.member.%d.ParameterValue' % count] = v
         return parameters
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/heat-2013.1/heat/common/crypt.py 
new/heat-2013.1.3.a2.g1689425/heat/common/crypt.py
--- old/heat-2013.1/heat/common/crypt.py        2013-04-04 18:19:11.000000000 
+0200
+++ new/heat-2013.1.3.a2.g1689425/heat/common/crypt.py  2013-06-13 
22:23:21.000000000 +0200
@@ -15,7 +15,7 @@
 
 import base64
 from Crypto.Cipher import AES
-from Crypto import Random
+from os import urandom
 
 from oslo.config import cfg
 
@@ -36,7 +36,7 @@
 def encrypt(auth_info):
     if auth_info is None:
         return None
-    iv = Random.new().read(AES.block_size)
+    iv = urandom(AES.block_size)
     cipher = AES.new(cfg.CONF.auth_encryption_key[:32], AES.MODE_CFB, iv)
     res = base64.b64encode(iv + cipher.encrypt(auth_info))
     return res
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/heat-2013.1/heat/tests/test_api_ec2token.py 
new/heat-2013.1.3.a2.g1689425/heat/tests/test_api_ec2token.py
--- old/heat-2013.1/heat/tests/test_api_ec2token.py     1970-01-01 
01:00:00.000000000 +0100
+++ new/heat-2013.1.3.a2.g1689425/heat/tests/test_api_ec2token.py       
2013-06-13 22:23:25.000000000 +0200
@@ -0,0 +1,315 @@
+# 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 mox
+import unittest
+from nose.plugins.attrib import attr
+
+import httplib
+import json
+from oslo.config import cfg
+
+from heat.api.aws import exception
+from heat.common.wsgi import Request
+from heat.api.aws import ec2token
+
+
+@attr(tag=['unit', 'api-aws', 'Ec2Token'])
+@attr(speed='fast')
+class Ec2TokenTest(unittest.TestCase):
+
+    '''
+    Tests the Ec2Token middleware
+    '''
+    def setUp(self):
+        self.m = mox.Mox()
+
+    def tearDown(self):
+        self.m.UnsetStubs()
+
+    def _dummy_GET_request(self, params={}, environ={}):
+        # Mangle the params dict into a query string
+        qs = "&".join(["=".join([k, str(params[k])]) for k in params])
+        environ.update({'REQUEST_METHOD': 'GET', 'QUERY_STRING': qs})
+        req = Request(environ)
+        return req
+
+    def test_get_signature_param_old(self):
+        params = {'Signature': 'foo'}
+        dummy_req = self._dummy_GET_request(params)
+        ec2 = ec2token.EC2Token(app=None, conf={})
+        self.assertEqual(ec2._get_signature(dummy_req), 'foo')
+
+    def test_get_signature_param_new(self):
+        params = {'X-Amz-Signature': 'foo'}
+        dummy_req = self._dummy_GET_request(params)
+        ec2 = ec2token.EC2Token(app=None, conf={})
+        self.assertEqual(ec2._get_signature(dummy_req), 'foo')
+
+    def test_get_signature_header_space(self):
+        req_env = {'HTTP_AUTHORIZATION':
+                   ('Authorization: foo  Credential=foo/bar, '
+                   'SignedHeaders=content-type;host;x-amz-date, '
+                   'Signature=xyz')}
+        dummy_req = self._dummy_GET_request(environ=req_env)
+        ec2 = ec2token.EC2Token(app=None, conf={})
+        self.assertEqual(ec2._get_signature(dummy_req), 'xyz')
+
+    def test_get_signature_header_notlast(self):
+        req_env = {'HTTP_AUTHORIZATION':
+                   ('Authorization: foo  Credential=foo/bar, '
+                    'Signature=xyz,'
+                    'SignedHeaders=content-type;host;x-amz-date ')}
+        dummy_req = self._dummy_GET_request(environ=req_env)
+        ec2 = ec2token.EC2Token(app=None, conf={})
+        self.assertEqual(ec2._get_signature(dummy_req), 'xyz')
+
+    def test_get_signature_header_nospace(self):
+        req_env = {'HTTP_AUTHORIZATION':
+                   ('Authorization: foo  Credential=foo/bar,'
+                   'SignedHeaders=content-type;host;x-amz-date,'
+                   'Signature=xyz')}
+        dummy_req = self._dummy_GET_request(environ=req_env)
+        ec2 = ec2token.EC2Token(app=None, conf={})
+        self.assertEqual(ec2._get_signature(dummy_req), 'xyz')
+
+    def test_get_access_param_old(self):
+        params = {'AWSAccessKeyId': 'foo'}
+        dummy_req = self._dummy_GET_request(params)
+        ec2 = ec2token.EC2Token(app=None, conf={})
+        self.assertEqual(ec2._get_access(dummy_req), 'foo')
+
+    def test_get_access_param_new(self):
+        params = {'X-Amz-Credential': 'foo/bar'}
+        dummy_req = self._dummy_GET_request(params)
+        ec2 = ec2token.EC2Token(app=None, conf={})
+        self.assertEqual(ec2._get_access(dummy_req), 'foo')
+
+    def test_get_access_header_space(self):
+        req_env = {'HTTP_AUTHORIZATION':
+                   ('Authorization: foo  Credential=foo/bar, '
+                   'SignedHeaders=content-type;host;x-amz-date, '
+                   'Signature=xyz')}
+        dummy_req = self._dummy_GET_request(environ=req_env)
+        ec2 = ec2token.EC2Token(app=None, conf={})
+        self.assertEqual(ec2._get_access(dummy_req), 'foo')
+
+    def test_get_access_header_nospace(self):
+        req_env = {'HTTP_AUTHORIZATION':
+                   ('Authorization: foo  Credential=foo/bar,'
+                   'SignedHeaders=content-type;host;x-amz-date,'
+                   'Signature=xyz')}
+        dummy_req = self._dummy_GET_request(environ=req_env)
+        ec2 = ec2token.EC2Token(app=None, conf={})
+        self.assertEqual(ec2._get_access(dummy_req), 'foo')
+
+    def test_get_access_header_last(self):
+        req_env = {'HTTP_AUTHORIZATION':
+                   ('Authorization: foo '
+                   'SignedHeaders=content-type;host;x-amz-date,'
+                   'Signature=xyz,Credential=foo/bar')}
+        dummy_req = self._dummy_GET_request(environ=req_env)
+        ec2 = ec2token.EC2Token(app=None, conf={})
+        self.assertEqual(ec2._get_access(dummy_req), 'foo')
+
+    def test_call_x_auth_user(self):
+        req_env = {'HTTP_X_AUTH_USER': 'foo'}
+        dummy_req = self._dummy_GET_request(environ=req_env)
+        ec2 = ec2token.EC2Token(app='xyz', conf={})
+        self.assertEqual(ec2.__call__(dummy_req), 'xyz')
+
+    def test_call_auth_nosig(self):
+        req_env = {'HTTP_AUTHORIZATION':
+                   ('Authorization: foo  Credential=foo/bar, '
+                   'SignedHeaders=content-type;host;x-amz-date')}
+        dummy_req = self._dummy_GET_request(environ=req_env)
+        ec2 = ec2token.EC2Token(app='xyz', conf={})
+        self.assertRaises(exception.HeatIncompleteSignatureError,
+                          ec2.__call__, dummy_req)
+
+    def test_call_auth_nouser(self):
+        req_env = {'HTTP_AUTHORIZATION':
+                   ('Authorization: foo '
+                   'SignedHeaders=content-type;host;x-amz-date,'
+                   'Signature=xyz')}
+        dummy_req = self._dummy_GET_request(environ=req_env)
+        ec2 = ec2token.EC2Token(app='xyz', conf={})
+        self.assertRaises(exception.HeatMissingAuthenticationTokenError,
+                          ec2.__call__, dummy_req)
+
+    def test_call_auth_noaccess(self):
+        # If there's no accesskey in params or header, but there is a
+        # Signature, we expect HeatMissingAuthenticationTokenError
+        params = {'Signature': 'foo'}
+        dummy_req = self._dummy_GET_request(params)
+        ec2 = ec2token.EC2Token(app='xyz', conf={})
+        self.assertRaises(exception.HeatMissingAuthenticationTokenError,
+                          ec2.__call__, dummy_req)
+
+    def test_call_x_auth_nouser_x_auth_user(self):
+        req_env = {'HTTP_X_AUTH_USER': 'foo',
+                   'HTTP_AUTHORIZATION':
+                   ('Authorization: foo '
+                   'SignedHeaders=content-type;host;x-amz-date,'
+                   'Signature=xyz')}
+        dummy_req = self._dummy_GET_request(environ=req_env)
+        ec2 = ec2token.EC2Token(app='xyz', conf={})
+        self.assertEqual(ec2.__call__(dummy_req), 'xyz')
+
+    def _stub_http_connection(self, headers={}, params={}, response=None):
+
+        class DummyHTTPResponse:
+            resp = response
+
+            def read(self):
+                return self.resp
+
+        self.m.StubOutWithMock(httplib.HTTPConnection, '__init__')
+        httplib.HTTPConnection.__init__(mox.IgnoreArg()).AndReturn(None)
+
+        self.m.StubOutWithMock(httplib.HTTPConnection, 'request')
+        body_hash = ('e3b0c44298fc1c149afbf4c8996fb9'
+                     '2427ae41e4649b934ca495991b7852b855')
+        req_creds = json.dumps({"ec2Credentials":
+                                {"access": "foo",
+                                 "headers": headers,
+                                 "host": "heat:8000",
+                                 "verb": "GET",
+                                 "params": params,
+                                 "signature": "xyz",
+                                 "path": "/v1",
+                                 "body_hash": body_hash}})
+        req_headers = {'Content-Type': 'application/json'}
+        req_path = '/foo'
+        httplib.HTTPConnection.request('POST', req_path,
+                                       body=req_creds,
+                                       headers=req_headers).AndReturn(None)
+
+        self.m.StubOutWithMock(httplib.HTTPConnection, 'getresponse')
+        httplib.HTTPConnection.getresponse().AndReturn(DummyHTTPResponse())
+
+        self.m.StubOutWithMock(httplib.HTTPConnection, 'close')
+        httplib.HTTPConnection.close().AndReturn(None)
+
+    def test_call_ok(self):
+        dummy_conf = {'auth_uri': 'http://123:5000/foo',
+                      'keystone_ec2_uri': 'http://456:5000/foo'}
+        ec2 = ec2token.EC2Token(app='woot', conf=dummy_conf)
+
+        auth_str = ('Authorization: foo  Credential=foo/bar, '
+                    'SignedHeaders=content-type;host;x-amz-date, '
+                    'Signature=xyz')
+        req_env = {'SERVER_NAME': 'heat',
+                   'SERVER_PORT': '8000',
+                   'PATH_INFO': '/v1',
+                   'HTTP_AUTHORIZATION': auth_str}
+        dummy_req = self._dummy_GET_request(environ=req_env)
+
+        ok_resp = json.dumps({'access': {'token': {'id': 123}}})
+        self._stub_http_connection(headers={'Authorization': auth_str},
+                                   response=ok_resp)
+        self.m.ReplayAll()
+        self.assertEqual(ec2.__call__(dummy_req), 'woot')
+
+        self.m.VerifyAll()
+
+    def test_call_err_tokenid(self):
+        dummy_conf = {'auth_uri': 'http://123:5000/foo',
+                      'keystone_ec2_uri': 'http://456:5000/foo'}
+        ec2 = ec2token.EC2Token(app='woot', conf=dummy_conf)
+
+        auth_str = ('Authorization: foo  Credential=foo/bar, '
+                    'SignedHeaders=content-type;host;x-amz-date, '
+                    'Signature=xyz')
+        req_env = {'SERVER_NAME': 'heat',
+                   'SERVER_PORT': '8000',
+                   'PATH_INFO': '/v1',
+                   'HTTP_AUTHORIZATION': auth_str}
+        dummy_req = self._dummy_GET_request(environ=req_env)
+
+        err_msg = "EC2 access key not found."
+        err_resp = json.dumps({'error': {'message': err_msg}})
+        self._stub_http_connection(headers={'Authorization': auth_str},
+                                   response=err_resp)
+        self.m.ReplayAll()
+        self.assertRaises(exception.HeatInvalidClientTokenIdError,
+                          ec2.__call__, dummy_req)
+
+        self.m.VerifyAll()
+
+    def test_call_err_signature(self):
+        dummy_conf = {'auth_uri': 'http://123:5000/foo',
+                      'keystone_ec2_uri': 'http://456:5000/foo'}
+        ec2 = ec2token.EC2Token(app='woot', conf=dummy_conf)
+
+        auth_str = ('Authorization: foo  Credential=foo/bar, '
+                    'SignedHeaders=content-type;host;x-amz-date, '
+                    'Signature=xyz')
+        req_env = {'SERVER_NAME': 'heat',
+                   'SERVER_PORT': '8000',
+                   'PATH_INFO': '/v1',
+                   'HTTP_AUTHORIZATION': auth_str}
+        dummy_req = self._dummy_GET_request(environ=req_env)
+
+        err_msg = "EC2 signature not supplied."
+        err_resp = json.dumps({'error': {'message': err_msg}})
+        self._stub_http_connection(headers={'Authorization': auth_str},
+                                   response=err_resp)
+        self.m.ReplayAll()
+        self.assertRaises(exception.HeatSignatureError,
+                          ec2.__call__, dummy_req)
+
+        self.m.VerifyAll()
+
+    def test_call_err_denied(self):
+        dummy_conf = {'auth_uri': 'http://123:5000/foo',
+                      'keystone_ec2_uri': 'http://456:5000/foo'}
+        ec2 = ec2token.EC2Token(app='woot', conf=dummy_conf)
+
+        auth_str = ('Authorization: foo  Credential=foo/bar, '
+                    'SignedHeaders=content-type;host;x-amz-date, '
+                    'Signature=xyz')
+        req_env = {'SERVER_NAME': 'heat',
+                   'SERVER_PORT': '8000',
+                   'PATH_INFO': '/v1',
+                   'HTTP_AUTHORIZATION': auth_str}
+        dummy_req = self._dummy_GET_request(environ=req_env)
+
+        err_resp = json.dumps({})
+        self._stub_http_connection(headers={'Authorization': auth_str},
+                                   response=err_resp)
+        self.m.ReplayAll()
+        self.assertRaises(exception.HeatAccessDeniedError,
+                          ec2.__call__, dummy_req)
+
+        self.m.VerifyAll()
+
+    def test_call_ok_v2(self):
+        dummy_conf = {'auth_uri': 'http://123:5000/foo',
+                      'keystone_ec2_uri': 'http://456:5000/foo'}
+        ec2 = ec2token.EC2Token(app='woot', conf=dummy_conf)
+        params = {'AWSAccessKeyId': 'foo', 'Signature': 'xyz'}
+        req_env = {'SERVER_NAME': 'heat',
+                   'SERVER_PORT': '8000',
+                   'PATH_INFO': '/v1'}
+        dummy_req = self._dummy_GET_request(params, req_env)
+
+        ok_resp = json.dumps({'access': {'token': {'id': 123}}})
+        self._stub_http_connection(response=ok_resp,
+                                   params={'AWSAccessKeyId': 'foo'})
+        self.m.ReplayAll()
+        self.assertEqual(ec2.__call__(dummy_req), 'woot')
+
+        self.m.VerifyAll()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/heat-2013.1/heat.egg-info/PKG-INFO 
new/heat-2013.1.3.a2.g1689425/heat.egg-info/PKG-INFO
--- old/heat-2013.1/heat.egg-info/PKG-INFO      2013-04-04 18:20:38.000000000 
+0200
+++ new/heat-2013.1.3.a2.g1689425/heat.egg-info/PKG-INFO        2013-06-13 
22:25:35.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: heat
-Version: 2013.1
+Version: 2013.1.3.a2.g1689425
 Summary: The heat project provides services for provisioning virtual machines
 Home-page: http://heat.openstack.org/
 Author: Heat API Developers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/heat-2013.1/heat.egg-info/SOURCES.txt 
new/heat-2013.1.3.a2.g1689425/heat.egg-info/SOURCES.txt
--- old/heat-2013.1/heat.egg-info/SOURCES.txt   2013-04-04 18:20:38.000000000 
+0200
+++ new/heat-2013.1.3.a2.g1689425/heat.egg-info/SOURCES.txt     2013-06-13 
22:25:39.000000000 +0200
@@ -252,6 +252,7 @@
 heat/tests/test_api_aws.py
 heat/tests/test_api_cfn_v1.py
 heat/tests/test_api_cloudwatch.py
+heat/tests/test_api_ec2token.py
 heat/tests/test_api_openstack_v1.py
 heat/tests/test_autoscaling.py
 heat/tests/test_cli.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/heat-2013.1/setup.py 
new/heat-2013.1.3.a2.g1689425/setup.py
--- old/heat-2013.1/setup.py    2013-04-04 18:19:16.000000000 +0200
+++ new/heat-2013.1.3.a2.g1689425/setup.py      2013-06-13 22:23:25.000000000 
+0200
@@ -24,7 +24,7 @@
 
 setuptools.setup(
     name=project,
-    version=setup.get_version(project, '2013.1'),
+    version=setup.get_version(project, '2013.1.3'),
     description='The heat project provides services for provisioning '
                 'virtual machines',
     license='Apache License (2.0)',

++++++ openstack-heat.init ++++++
--- /var/tmp/diff_new_pack.jaDiCW/_old  2013-06-20 21:25:11.000000000 +0200
+++ /var/tmp/diff_new_pack.jaDiCW/_new  2013-06-20 21:25:11.000000000 +0200
@@ -14,7 +14,7 @@
 
 DAEMON="__NAME__"
 USER="openstack-heat"
-FLAGFILE="/etc/heat/heat-$DAEMON.conf"
+CONFIGFILE="/etc/heat/heat-$DAEMON.conf"
 RUNDIR="/var/run/cinder"
 
 # $RUNDIR can be tmpfs, thus we have to create/own it here:
@@ -25,7 +25,7 @@
 case "$1" in
     start)
        echo -n "Starting heat-$DAEMON"
-       /sbin/startproc -q -s -u $USER /usr/bin/heat-$DAEMON 
--flagfile=$FLAGFILE
+       /sbin/startproc -q -s -u $USER /usr/bin/heat-$DAEMON 
--config-file=$CONFIGFILE
         rc_status -v
         ;;
     stop)

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to