summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClay Gerrard <clay.gerrard@gmail.com>2023-04-04 15:55:53 -0500
committerClay Gerrard <clay.gerrard@gmail.com>2023-04-28 10:03:59 -0500
commitab03e057d774b8a3b9b5310c10a76b282df020ad (patch)
tree8f223e8721782b463ddf69b5f08aaf873cc9992a
parentc95f8e6c050bbe9244122100ca90e6f335c73ab7 (diff)
downloadswift-ab03e057d774b8a3b9b5310c10a76b282df020ad.tar.gz
Make all config parsing case-sensitive
This effects both daemon config parsing and paste-deploy config parsing when using conf.d. When the WSGI servers were loaded from a flat file they have always been case-sensitive. This difference was surprising (who wants anything case-insensitive?) and potentially dangerous for values like RECLAIM_AGE. UpgradeImpact: Previously the option keys in swift's configuration .ini files were sometimes parsed in a case-insensitive manner, so you could use CLIENT_TIMEOUT and the daemons would recognize you meant client_timeout. Now upper-case or mixed-case option names, such as CLIENT_TIMEOUT or Client_Timeout, will be ignored. Change-Id: Idd8e552d9fe98b84d7cee1adfa431ea3ae93345d
-rw-r--r--swift/common/utils/__init__.py1
-rw-r--r--test/unit/common/test_daemon.py16
-rw-r--r--test/unit/common/test_wsgi.py8
3 files changed, 20 insertions, 5 deletions
diff --git a/swift/common/utils/__init__.py b/swift/common/utils/__init__.py
index 16dc58807..13ec9443a 100644
--- a/swift/common/utils/__init__.py
+++ b/swift/common/utils/__init__.py
@@ -2542,6 +2542,7 @@ def readconf(conf_path, section_name=None, log_name=None, defaults=None,
# values like "1%" (which we want to support for
# fallocate_reserve).
c = ConfigParser(defaults, interpolation=NicerInterpolation())
+ c.optionxform = str # Don't lower-case keys
if hasattr(conf_path, 'readline'):
if hasattr(conf_path, 'seek'):
diff --git a/test/unit/common/test_daemon.py b/test/unit/common/test_daemon.py
index 94c7917bc..9dc190e5c 100644
--- a/test/unit/common/test_daemon.py
+++ b/test/unit/common/test_daemon.py
@@ -226,7 +226,8 @@ class TestRunDaemon(unittest.TestCase, ConfigAssertMixin):
d = daemon.run_daemon(MyDaemon, conf_path)
# my-daemon section takes priority (!?)
self.assertEqual('2', d.conf['client_timeout'])
- self.assertEqual('10', d.conf['conn_timeout'])
+ self.assertEqual('10', d.conf['CONN_timeout'])
+ self.assertEqual('5', d.conf['conn_timeout'])
@with_tempdir
def test_run_daemon_from_conf_file_with_duplicate_var(self, tempdir):
@@ -237,13 +238,16 @@ class TestRunDaemon(unittest.TestCase, ConfigAssertMixin):
[my-daemon]
CLIENT_TIMEOUT = 2
client_timeout = 1
+ conn_timeout = 1.1
+ conn_timeout = 1.2
"""
contents = dedent(conf_body)
with open(conf_path, 'w') as f:
f.write(contents)
with mock.patch('swift.common.daemon.use_hub'):
app_config = lambda: daemon.run_daemon(MyDaemon, tempdir)
- self.assertDuplicateOption(app_config, 'client_timeout', '1')
+ # N.B. CLIENT_TIMEOUT/client_timeout are unique options
+ self.assertDuplicateOption(app_config, 'conn_timeout', '1.2')
@with_tempdir
def test_run_deamon_from_conf_dir(self, tempdir):
@@ -270,7 +274,8 @@ class TestRunDaemon(unittest.TestCase, ConfigAssertMixin):
d = daemon.run_daemon(MyDaemon, tempdir)
# my-daemon section takes priority (!?)
self.assertEqual('2', d.conf['client_timeout'])
- self.assertEqual('10', d.conf['conn_timeout'])
+ self.assertEqual('10', d.conf['CONN_timeout'])
+ self.assertEqual('5', d.conf['conn_timeout'])
@with_tempdir
def test_run_daemon_from_conf_dir_with_duplicate_var(self, tempdir):
@@ -283,6 +288,8 @@ class TestRunDaemon(unittest.TestCase, ConfigAssertMixin):
[my-daemon]
client_timeout = 2
CLIENT_TIMEOUT = 4
+ conn_timeout = 1.1
+ conn_timeout = 1.2
""",
}
for filename, conf_body in conf_files.items():
@@ -291,7 +298,8 @@ class TestRunDaemon(unittest.TestCase, ConfigAssertMixin):
fd.write(dedent(conf_body))
with mock.patch('swift.common.daemon.use_hub'):
app_config = lambda: daemon.run_daemon(MyDaemon, tempdir)
- self.assertDuplicateOption(app_config, 'client_timeout', '4')
+ # N.B. CLIENT_TIMEOUT/client_timeout are unique options
+ self.assertDuplicateOption(app_config, 'conn_timeout', '1.2')
@contextmanager
def mock_os(self, child_worker_cycles=3):
diff --git a/test/unit/common/test_wsgi.py b/test/unit/common/test_wsgi.py
index 39349ffa3..b6a384354 100644
--- a/test/unit/common/test_wsgi.py
+++ b/test/unit/common/test_wsgi.py
@@ -148,6 +148,8 @@ class TestWSGI(unittest.TestCase, ConfigAssertMixin):
app = wsgi.loadapp(conf_path)
self.assertIsInstance(app, obj_server.ObjectController)
self.assertTrue(isinstance(app, obj_server.ObjectController))
+ # N.B. paste config loading from *file* is already case-sensitive,
+ # so, CLIENT_TIMEOUT/client_timeout are unique options
self.assertEqual(1, app.client_timeout)
self.assertEqual(5, app.conn_timeout)
@@ -298,6 +300,8 @@ class TestWSGI(unittest.TestCase, ConfigAssertMixin):
use = egg:swift#proxy
client_timeout = 2
CLIENT_TIMEOUT = 1
+ conn_timeout = 3
+ conn_timeout = 4
""",
}
_fake_rings(tempdir)
@@ -306,7 +310,9 @@ class TestWSGI(unittest.TestCase, ConfigAssertMixin):
with open(path, 'wt') as fd:
fd.write(dedent(conf_body))
app_config = lambda: wsgi.loadapp(tempdir)
- self.assertDuplicateOption(app_config, 'client_timeout', 2.0)
+ # N.B. our paste conf.d parsing re-uses readconf,
+ # so, CLIENT_TIMEOUT/client_timeout are unique options
+ self.assertDuplicateOption(app_config, 'conn_timeout', 4.0)
@with_tempdir
def test_load_app_config(self, tempdir):