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]
