Allow multiple storage_domain in cname_lookup.

Implements: blueprint multiple-domains-in-domain-remap
Change-Id: Ia647f6777717e9ff4955ea66b29f072ac03d2785
This commit is contained in:
Chmouel Boudjnah 2013-08-12 13:04:40 +02:00 committed by Gerrit Code Review
parent 61f9380225
commit 053cd092b1
3 changed files with 62 additions and 6 deletions

View File

@ -390,7 +390,10 @@ use = egg:swift#cname_lookup
# set log_headers = false
# set log_address = /dev/log
#
# Specify the storage_domain that match your cloud, multiple domains
# can be specified separated by a comma
# storage_domain = example.com
#
# lookup_depth = 1
# Note: Put staticweb just after your auth filter(s) in the pipeline

View File

@ -41,7 +41,7 @@ else: # executed if the try block finishes with no errors
MODULE_DEPENDENCY_MET = True
from swift.common.swob import Request, HTTPBadRequest
from swift.common.utils import cache_from_env, get_logger
from swift.common.utils import cache_from_env, get_logger, list_from_csv
def lookup_cname(domain): # pragma: no cover
@ -89,13 +89,22 @@ class CNAMELookupMiddleware(object):
# reraise the exception if the dependency wasn't met
raise ImportError('dnspython is required for this module')
self.app = app
self.storage_domain = conf.get('storage_domain', 'example.com')
if self.storage_domain and self.storage_domain[0] != '.':
self.storage_domain = '.' + self.storage_domain
storage_domain = conf.get('storage_domain', 'example.com')
self.storage_domain = ['.' + s for s in
list_from_csv(storage_domain)
if not s.startswith('.')]
self.storage_domain += [s for s in list_from_csv(storage_domain)
if s.startswith('.')]
self.lookup_depth = int(conf.get('lookup_depth', '1'))
self.memcache = None
self.logger = get_logger(conf, log_route='cname-lookup')
def _domain_endswith_in_storage_domain(self, a_domain):
for domain in self.storage_domain:
if a_domain.endswith(domain):
return True
return False
def __call__(self, env, start_response):
if not self.storage_domain:
return self.app(env, start_response)
@ -111,7 +120,7 @@ class CNAMELookupMiddleware(object):
if is_ip(given_domain):
return self.app(env, start_response)
a_domain = given_domain
if not a_domain.endswith(self.storage_domain):
if not self._domain_endswith_in_storage_domain(a_domain):
if self.memcache is None:
self.memcache = cache_from_env(env)
error = True
@ -131,7 +140,7 @@ class CNAMELookupMiddleware(object):
error = True
found_domain = None
break
elif found_domain.endswith(self.storage_domain):
elif self._domain_endswith_in_storage_domain(found_domain):
# Found it!
self.logger.info(
_('Mapped %(given_domain)s to %(found_domain)s') %

View File

@ -14,6 +14,7 @@
# limitations under the License.
import unittest
import mock
from nose import SkipTest
try:
@ -193,3 +194,46 @@ class TestCNAMELookup(unittest.TestCase):
resp = app(req.environ, start_response)
self.assertEquals(resp, 'FAKE APP')
def test_storage_domains_conf_format(self):
conf = {'storage_domain': 'foo.com'}
app = cname_lookup.filter_factory(conf)(FakeApp())
self.assertEquals(app.storage_domain, ['.foo.com'])
conf = {'storage_domain': 'foo.com, '}
app = cname_lookup.filter_factory(conf)(FakeApp())
self.assertEquals(app.storage_domain, ['.foo.com'])
conf = {'storage_domain': 'foo.com, bar.com'}
app = cname_lookup.filter_factory(conf)(FakeApp())
self.assertEquals(app.storage_domain, ['.foo.com', '.bar.com'])
conf = {'storage_domain': 'foo.com, .bar.com'}
app = cname_lookup.filter_factory(conf)(FakeApp())
self.assertEquals(app.storage_domain, ['.foo.com', '.bar.com'])
conf = {'storage_domain': '.foo.com, .bar.com'}
app = cname_lookup.filter_factory(conf)(FakeApp())
self.assertEquals(app.storage_domain, ['.foo.com', '.bar.com'])
def test_multiple_storage_domains(self):
conf = {'storage_domain': 'storage1.com, storage2.com',
'lookup_depth': 2}
app = cname_lookup.CNAMELookupMiddleware(FakeApp(), conf)
def do_test(lookup_back):
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'c.a.example.com'})
module = 'swift.common.middleware.cname_lookup.lookup_cname'
with mock.patch(module, lambda x: (0, lookup_back)):
return app(req.environ, start_response)
resp = do_test('c.storage1.com')
self.assertEquals(resp, 'FAKE APP')
resp = do_test('c.storage2.com')
self.assertEquals(resp, 'FAKE APP')
bad_domain = ['CNAME lookup failed to resolve to a valid domain']
resp = do_test('c.badtest.com')
self.assertEquals(resp, bad_domain)