From 24ffbf53562a11954ad5fd0160dfa9e53d14e94f Mon Sep 17 00:00:00 2001 From: Clint Byrum Date: Wed, 3 Jul 2013 12:44:37 -0700 Subject: [PATCH] Fix problems exposed by trying against heat-api-cfn. --- os_collect_config/cfn.py | 34 ++++++++++++++++++++--------- os_collect_config/tests/test_cfn.py | 14 ++++++++---- requirements.txt | 1 + 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/os_collect_config/cfn.py b/os_collect_config/cfn.py index c3ce19e..b1ab413 100644 --- a/os_collect_config/cfn.py +++ b/os_collect_config/cfn.py @@ -15,6 +15,7 @@ import json from keystoneclient.contrib.ec2 import utils as ec2_utils +from lxml import etree from oslo.config import cfg import urlparse @@ -76,7 +77,7 @@ class Collector(object): else: sub_path = '' params = {'Action': 'DescribeStackResource', - 'Stackname': stack_name, + 'StackName': stack_name, 'LogicalResourceId': resource, 'AWSAccessKeyId': CONF.cfn.access_key_id, 'SignatureVersion': '2'} @@ -85,7 +86,7 @@ class Collector(object): 'verb': 'GET', 'host': parsed_url.netloc, 'path': parsed_url.path} - params['Authorization'] = signer.generate(credentials) + params['Signature'] = signer.generate(credentials) try: content = self._session.get( url, params=params, headers=headers) @@ -93,13 +94,26 @@ class Collector(object): except self._requests_impl.exceptions.RequestException as e: logger.warn(e) raise exc.CfnMetadataNotAvailable - map_content = json.loads(content.text) + map_content = etree.fromstring(content.text) + resource_detail = map_content.find( + 'DescribeStackResourceResult').find('StackResourceDetail') + sub_element = resource_detail.find(field) + if sub_element is None: + logger.warn('Path %s does not exist.' % (path)) + raise exc.CfnMetadataNotAvailable + try: + value = json.loads(sub_element.text) + except ValueError as e: + logger.warn( + 'Path %s failed to parse as json. (%s)' % (path, e)) + raise exc.CfnMetadataNotAvailable if sub_path: - if sub_path not in map_content: - logger.warn('Sub-path could not be found for Resource (%s)' - % path) - raise exc.CfnMetadataNotConfigured - map_content = map_content[sub_path] - - final_content.update(map_content) + for subkey in sub_path.split('.'): + try: + value = value[subkey] + except KeyError: + logger.warn( + 'Sub-key %s does not exist. (%s)' % (subkey, path)) + raise exc.CfnMetadataNotAvailable + final_content.update(value) return final_content diff --git a/os_collect_config/tests/test_cfn.py b/os_collect_config/tests/test_cfn.py index 88ca315..50710fb 100644 --- a/os_collect_config/tests/test_cfn.py +++ b/os_collect_config/tests/test_cfn.py @@ -15,6 +15,7 @@ import fixtures import json +from lxml import etree from oslo.config import cfg import requests import testtools @@ -60,13 +61,18 @@ class FakeRequests(object): headers['Content-Type']) self._test.assertIn('SignatureVersion', params) self._test.assertEquals('2', params['SignatureVersion']) - self._test.assertIn('Authorization', params) + self._test.assertIn('Signature', params) self._test.assertIn('Action', params) self._test.assertEquals('DescribeStackResource', params['Action']) self._test.assertIn('LogicalResourceId', params) self._test.assertEquals('foo', params['LogicalResourceId']) - return FakeResponse(json.dumps(META_DATA)) + root = etree.Element('DescribeStackResourceResponse') + result = etree.SubElement(root, 'DescribeStackResourceResult') + detail = etree.SubElement(result, 'StackResourceDetail') + metadata = etree.SubElement(detail, 'Metadata') + metadata.text = json.dumps(META_DATA) + return FakeResponse(etree.tostring(root)) return FakeReqSession(self._test) @@ -124,8 +130,8 @@ class TestCfn(testtools.TestCase): def test_collect_cfn_missing_sub_path(self): cfg.CONF.cfn.path = ['foo.Metadata.not_there'] cfn_collect = cfn.Collector(requests_impl=FakeRequests(self)) - self.assertRaises(exc.CfnMetadataNotConfigured, cfn_collect.collect) - self.assertIn('Sub-path could not be found', self.log.output) + self.assertRaises(exc.CfnMetadataNotAvailable, cfn_collect.collect) + self.assertIn('Sub-key not_there does not exist', self.log.output) def test_collect_cfn_sub_path(self): cfg.CONF.cfn.path = ['foo.Metadata.map_ab'] diff --git a/requirements.txt b/requirements.txt index 1a757c9..c371d94 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,6 +5,7 @@ eventlet>=0.12.0 python-keystoneclient requests iso8601>=0.1.4 +lxml>=2.3 oslo.config>=1.1.0 pbr six