From 99c575f04366d76cb195d7cd912714f3a0be7ede Mon Sep 17 00:00:00 2001 From: Joona Hoikkala Date: Wed, 13 Jan 2016 23:56:22 +0200 Subject: [PATCH 1/8] Check augeas version, and raise error if not recent enough --- .../letsencrypt_apache/configurator.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/letsencrypt-apache/letsencrypt_apache/configurator.py b/letsencrypt-apache/letsencrypt_apache/configurator.py index 4066d6264..00b93bb6e 100644 --- a/letsencrypt-apache/letsencrypt_apache/configurator.py +++ b/letsencrypt-apache/letsencrypt_apache/configurator.py @@ -158,6 +158,11 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): raise errors.NotSupportedError( "Apache Version %s not supported.", str(self.version)) + if not self._check_aug_version(): + raise errors.NotSupportedError( + "Your libaugeas0 is outdated, upgrade it from backports " + " or re-bootstrap letsencrypt") + self.parser = parser.ApacheParser( self.aug, self.conf("server-root"), self.conf("vhost-root"), self.version) @@ -169,6 +174,17 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): install_ssl_options_conf(self.mod_ssl_conf) + def _check_aug_version(self): + """ Checks that we have recent enough version of libaugeas. + If augeas version is recent enough, it will support case insensitive + regexp matching""" + + self.aug.set("/test/path/testing/arg", "aRgUMeNT") + matches = self.aug.match( + "/test//*[self::arg=~regexp('argument', 'i')]") + self.aug.remove("/test/path") + return matches + def deploy_cert(self, domain, cert_path, key_path, chain_path=None, fullchain_path=None): # pylint: disable=unused-argument """Deploys certificate to specified virtual host. From 30ad7dce9fb74f1fd8a401d16641fe8b49b1e06d Mon Sep 17 00:00:00 2001 From: Joona Hoikkala Date: Thu, 14 Jan 2016 00:06:52 +0200 Subject: [PATCH 2/8] Pick up the augeas RuntimeError and pass the correct one --- letsencrypt-apache/letsencrypt_apache/configurator.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/letsencrypt-apache/letsencrypt_apache/configurator.py b/letsencrypt-apache/letsencrypt_apache/configurator.py index 00b93bb6e..0c4d65c28 100644 --- a/letsencrypt-apache/letsencrypt_apache/configurator.py +++ b/letsencrypt-apache/letsencrypt_apache/configurator.py @@ -180,8 +180,11 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): regexp matching""" self.aug.set("/test/path/testing/arg", "aRgUMeNT") - matches = self.aug.match( - "/test//*[self::arg=~regexp('argument', 'i')]") + try: + matches = self.aug.match( + "/test//*[self::arg=~regexp('argument', 'i')]") + except RuntimeError: + return None self.aug.remove("/test/path") return matches From 7d51480c4dd8610c40d8e4aa4e78024e12e46e63 Mon Sep 17 00:00:00 2001 From: Joona Hoikkala Date: Thu, 14 Jan 2016 00:23:45 +0200 Subject: [PATCH 3/8] Remove the test path from augeas even if failing --- letsencrypt-apache/letsencrypt_apache/configurator.py | 1 + 1 file changed, 1 insertion(+) diff --git a/letsencrypt-apache/letsencrypt_apache/configurator.py b/letsencrypt-apache/letsencrypt_apache/configurator.py index 0c4d65c28..72db9c853 100644 --- a/letsencrypt-apache/letsencrypt_apache/configurator.py +++ b/letsencrypt-apache/letsencrypt_apache/configurator.py @@ -184,6 +184,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): matches = self.aug.match( "/test//*[self::arg=~regexp('argument', 'i')]") except RuntimeError: + self.aug.remove("/test/path") return None self.aug.remove("/test/path") return matches From ddbfb440412187447d4d51f0f7ac03025954aebf Mon Sep 17 00:00:00 2001 From: Joona Hoikkala Date: Thu, 14 Jan 2016 00:50:34 +0200 Subject: [PATCH 4/8] Add tests --- letsencrypt-apache/letsencrypt_apache/configurator.py | 2 +- .../letsencrypt_apache/tests/configurator_test.py | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/letsencrypt-apache/letsencrypt_apache/configurator.py b/letsencrypt-apache/letsencrypt_apache/configurator.py index 72db9c853..ad407a3bc 100644 --- a/letsencrypt-apache/letsencrypt_apache/configurator.py +++ b/letsencrypt-apache/letsencrypt_apache/configurator.py @@ -185,7 +185,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): "/test//*[self::arg=~regexp('argument', 'i')]") except RuntimeError: self.aug.remove("/test/path") - return None + return False self.aug.remove("/test/path") return matches diff --git a/letsencrypt-apache/letsencrypt_apache/tests/configurator_test.py b/letsencrypt-apache/letsencrypt_apache/tests/configurator_test.py index 113b3b2b2..ce3d20297 100644 --- a/letsencrypt-apache/letsencrypt_apache/tests/configurator_test.py +++ b/letsencrypt-apache/letsencrypt_apache/tests/configurator_test.py @@ -978,6 +978,13 @@ class TwoVhost80Test(util.ApacheTest): self.assertTrue(self.config.parser.find_dir( "NameVirtualHost", "*:443", exclude=False)) + def test_aug_version(self): + mock_match = mock.Mock(return_value=["something"]) + self.config.aug.match = mock_match + self.assertEquals(self.config._check_aug_version(), ["something"]) + self.config.aug.match.side_effect = RuntimeError + self.assertFalse(self.config._check_aug_version()) + if __name__ == "__main__": unittest.main() # pragma: no cover From d0832f741462cfa94046d7ed7a81835a8836e1e8 Mon Sep 17 00:00:00 2001 From: Joona Hoikkala Date: Thu, 14 Jan 2016 01:09:28 +0200 Subject: [PATCH 5/8] Added the missing test --- .../letsencrypt_apache/tests/configurator_test.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/letsencrypt-apache/letsencrypt_apache/tests/configurator_test.py b/letsencrypt-apache/letsencrypt_apache/tests/configurator_test.py index ce3d20297..fe7071f14 100644 --- a/letsencrypt-apache/letsencrypt_apache/tests/configurator_test.py +++ b/letsencrypt-apache/letsencrypt_apache/tests/configurator_test.py @@ -65,6 +65,15 @@ class TwoVhost80Test(util.ApacheTest): self.assertRaises( errors.NotSupportedError, self.config.prepare) + @mock.patch("letsencrypt_apache.parser.ApacheParser") + @mock.patch("letsencrypt_apache.configurator.le_util.exe_exists") + def test_prepare_old_aug(self, mock_exe_exists, _): + mock_exe_exists.return_value = True + self.config._check_aug_version = mock.Mock(return_value=False) + self.assertRaises( + errors.NotSupportedError, self.config.prepare) + + def test_add_parser_arguments(self): # pylint: disable=no-self-use from letsencrypt_apache.configurator import ApacheConfigurator # Weak test.. From 8f6ef8db5301ce4087a1de86eeaaaeda805f93f9 Mon Sep 17 00:00:00 2001 From: Joona Hoikkala Date: Thu, 14 Jan 2016 01:10:50 +0200 Subject: [PATCH 6/8] Modified error message --- letsencrypt-apache/letsencrypt_apache/configurator.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/letsencrypt-apache/letsencrypt_apache/configurator.py b/letsencrypt-apache/letsencrypt_apache/configurator.py index ad407a3bc..47d238140 100644 --- a/letsencrypt-apache/letsencrypt_apache/configurator.py +++ b/letsencrypt-apache/letsencrypt_apache/configurator.py @@ -160,8 +160,9 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): if not self._check_aug_version(): raise errors.NotSupportedError( - "Your libaugeas0 is outdated, upgrade it from backports " - " or re-bootstrap letsencrypt") + "Apache plugin support requires libaugeas0 and augeas-lenses " + "version 1.2.0 or higher, please make sure you have you have " + "those installed.") self.parser = parser.ApacheParser( self.aug, self.conf("server-root"), self.conf("vhost-root"), From 8c110e31d75a746ec6bb284bba61179140d445a9 Mon Sep 17 00:00:00 2001 From: Joona Hoikkala Date: Thu, 14 Jan 2016 01:30:34 +0200 Subject: [PATCH 7/8] Fixed tests --- .../letsencrypt_apache/tests/configurator_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/letsencrypt-apache/letsencrypt_apache/tests/configurator_test.py b/letsencrypt-apache/letsencrypt_apache/tests/configurator_test.py index fe7071f14..5052da893 100644 --- a/letsencrypt-apache/letsencrypt_apache/tests/configurator_test.py +++ b/letsencrypt-apache/letsencrypt_apache/tests/configurator_test.py @@ -69,11 +69,11 @@ class TwoVhost80Test(util.ApacheTest): @mock.patch("letsencrypt_apache.configurator.le_util.exe_exists") def test_prepare_old_aug(self, mock_exe_exists, _): mock_exe_exists.return_value = True + self.config.config_test = mock.Mock() self.config._check_aug_version = mock.Mock(return_value=False) self.assertRaises( errors.NotSupportedError, self.config.prepare) - def test_add_parser_arguments(self): # pylint: disable=no-self-use from letsencrypt_apache.configurator import ApacheConfigurator # Weak test.. From fe8a0dcef26c15480ce0ae86f8f24450836e14a6 Mon Sep 17 00:00:00 2001 From: Joona Hoikkala Date: Thu, 14 Jan 2016 01:52:35 +0200 Subject: [PATCH 8/8] Make linter happy --- .../letsencrypt_apache/tests/configurator_test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/letsencrypt-apache/letsencrypt_apache/tests/configurator_test.py b/letsencrypt-apache/letsencrypt_apache/tests/configurator_test.py index 5052da893..2a32b04be 100644 --- a/letsencrypt-apache/letsencrypt_apache/tests/configurator_test.py +++ b/letsencrypt-apache/letsencrypt_apache/tests/configurator_test.py @@ -70,7 +70,7 @@ class TwoVhost80Test(util.ApacheTest): def test_prepare_old_aug(self, mock_exe_exists, _): mock_exe_exists.return_value = True self.config.config_test = mock.Mock() - self.config._check_aug_version = mock.Mock(return_value=False) + self.config._check_aug_version = mock.Mock(return_value=False) # pylint: disable=protected-access self.assertRaises( errors.NotSupportedError, self.config.prepare) @@ -990,9 +990,9 @@ class TwoVhost80Test(util.ApacheTest): def test_aug_version(self): mock_match = mock.Mock(return_value=["something"]) self.config.aug.match = mock_match - self.assertEquals(self.config._check_aug_version(), ["something"]) + self.assertEquals(self.config._check_aug_version(), ["something"]) # pylint: disable=protected-access self.config.aug.match.side_effect = RuntimeError - self.assertFalse(self.config._check_aug_version()) + self.assertFalse(self.config._check_aug_version()) # pylint: disable=protected-access if __name__ == "__main__":