]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Add support for local file urls
authorAngus Salkeld <asalkeld@redhat.com>
Mon, 26 Aug 2013 04:37:05 +0000 (14:37 +1000)
committerAngus Salkeld <asalkeld@redhat.com>
Wed, 28 Aug 2013 01:00:48 +0000 (11:00 +1000)
Change-Id: Ie54508ade52b80790d11958a820998c902d10fd7

heat/common/urlfetch.py
heat/tests/test_urlfetch.py

index 623ce148b22f55c60ef4fdee90db30f7e6999c06..b2cdaf11edad958db4be034d42eaf3caa9497232 100644 (file)
@@ -19,6 +19,7 @@ Utility for fetching a resource (e.g. a template) from a URL.
 
 import requests
 from requests import exceptions
+import urllib2
 import urlparse
 
 from heat.openstack.common import log as logging
@@ -27,20 +28,28 @@ from heat.openstack.common.gettextutils import _
 logger = logging.getLogger(__name__)
 
 
-def get(url):
+def get(url, allowed_schemes=('http', 'https')):
     '''
     Get the data at the specifier URL.
 
     The URL must use the http: or https: schemes.
+    The file: scheme is also supported if you override
+    the allowed_schemes argument.
     Raise an IOError if getting the data fails.
     '''
     logger.info(_('Fetching data from %s') % url)
 
     components = urlparse.urlparse(url)
 
-    if components.scheme not in ('http', 'https'):
+    if components.scheme not in allowed_schemes:
         raise IOError('Invalid URL scheme %s' % components.scheme)
 
+    if components.scheme == 'file':
+        try:
+            return urllib2.urlopen(url).read()
+        except urllib2.URLError as uex:
+            raise IOError('Failed to retrieve template: %s' % str(uex))
+
     try:
         resp = requests.get(url)
         resp.raise_for_status()
index 776d8d8fb7237e10f6878f4fb20a8ec0a1b41577..df358b24ff03ba886b7791f29ab55b2149d5f0ce 100644 (file)
@@ -15,6 +15,8 @@
 
 import requests
 from requests import exceptions
+import urllib2
+import cStringIO
 
 from heat.common import urlfetch
 from heat.tests.common import HeatTestCase
@@ -37,11 +39,32 @@ class UrlFetchTest(HeatTestCase):
         super(UrlFetchTest, self).setUp()
         self.m.StubOutWithMock(requests, 'get')
 
-    def test_file_scheme(self):
+    def test_file_scheme_default_behaviour(self):
         self.m.ReplayAll()
         self.assertRaises(IOError, urlfetch.get, 'file:///etc/profile')
         self.m.VerifyAll()
 
+    def test_file_scheme_supported(self):
+        data = '{ "foo": "bar" }'
+        url = 'file:///etc/profile'
+
+        self.m.StubOutWithMock(urllib2, 'urlopen')
+        urllib2.urlopen(url).AndReturn(cStringIO.StringIO(data))
+        self.m.ReplayAll()
+
+        self.assertEqual(data, urlfetch.get(url, allowed_schemes=['file']))
+        self.m.VerifyAll()
+
+    def test_file_scheme_failure(self):
+        url = 'file:///etc/profile'
+
+        self.m.StubOutWithMock(urllib2, 'urlopen')
+        urllib2.urlopen(url).AndRaise(urllib2.URLError('oops'))
+        self.m.ReplayAll()
+
+        self.assertRaises(IOError, urlfetch.get, url, allowed_schemes=['file'])
+        self.m.VerifyAll()
+
     def test_http_scheme(self):
         url = 'http://example.com/template'
         data = '{ "foo": "bar" }'