diff options
author | Clay Gerrard <clay.gerrard@gmail.com> | 2023-04-04 15:55:53 -0500 |
---|---|---|
committer | Clay Gerrard <clay.gerrard@gmail.com> | 2023-04-28 10:03:59 -0500 |
commit | ab03e057d774b8a3b9b5310c10a76b282df020ad (patch) | |
tree | 8f223e8721782b463ddf69b5f08aaf873cc9992a | |
parent | c95f8e6c050bbe9244122100ca90e6f335c73ab7 (diff) | |
download | swift-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__.py | 1 | ||||
-rw-r--r-- | test/unit/common/test_daemon.py | 16 | ||||
-rw-r--r-- | test/unit/common/test_wsgi.py | 8 |
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): |