diff options
author | Joona Hoikkala <joona@kuori.org> | 2019-08-05 21:01:18 +0300 |
---|---|---|
committer | Joona Hoikkala <joona@kuori.org> | 2019-08-05 21:01:18 +0300 |
commit | ff0d851a1e8ed97272aeb3b3dbc173389b77db5c (patch) | |
tree | 1f026cd245d647233e4e42ebc777f18039f24bfa | |
parent | 5cfdfc80bd45a9a37946dba84ae02c481cebd789 (diff) |
-rw-r--r-- | certbot-apache/certbot_apache/augeasparser.py | 87 | ||||
-rw-r--r-- | certbot-apache/certbot_apache/configurator.py | 62 | ||||
-rw-r--r-- | certbot-apache/certbot_apache/parserassert.py | 33 |
3 files changed, 166 insertions, 16 deletions
diff --git a/certbot-apache/certbot_apache/augeasparser.py b/certbot-apache/certbot_apache/augeasparser.py new file mode 100644 index 000000000..b510a21eb --- /dev/null +++ b/certbot-apache/certbot_apache/augeasparser.py @@ -0,0 +1,87 @@ +""" Tests for ParserNode interface """ +from certbot_apache import interfaces + + +class AugeasCommentNode(interfaces.CommentNode): + """ Augeas implementation of CommentNode interface """ + ancestor = None + comment = "" + dirty = False + + def __init__(self, comment, ancestor=None): + self.comment = comment + self.ancestor = ancestor + + def save(self, msg): # pragma: no cover + pass + + +class AugeasDirectiveNode(interfaces.DirectiveNode): + """ Augeas implementation of DirectiveNode interface """ + ancestor = None + parameters = tuple() # type: Tuple[str, ...] + dirty = False + enabled = True + name = "" + + def __init__(self, name, parameters=tuple(), ancestor=None): + self.name = name + self.parameters = parameters + self.ancestor = ancestor + + def save(self, msg): # pragma: no cover + pass + + def set_parameters(self, parameters): # pragma: no cover + self.parameters = tuple("CERTBOT_PASS_ASSERT") + + +class AugeasBlockNode(interfaces.BlockNode): + """ Augeas implementation of BlockNode interface """ + ancestor = None + parameters = tuple() # type: Tuple[str, ...] + children = tuple() # type: Tuple[interfaces.ParserNode, ...] + dirty = False + enabled = True + name = "" + + def __init__(self, name, parameters=tuple(), ancestor=None): + self.name = name + self.parameters = parameters + self.ancestor = ancestor + + def save(self, msg): # pragma: no cover + pass + + def add_child_block(self, name, parameters=None, position=None): # pragma: no cover + new_block = AugeasBlockNode("CERTBOT_PASS_ASSERT", ancestor=self) + self.children += (new_block,) + return new_block + + def add_child_directive(self, name, parameters=None, position=None): # pragma: no cover + new_dir = AugeasDirectiveNode("CERTBOT_PASS_ASSERT", ancestor=self) + self.children += (new_dir,) + return new_dir + + def add_child_comment(self, comment="", position=None): # pragma: no cover + new_comment = AugeasCommentNode("CERTBOT_PASS_ASSERT", ancestor=self) + self.children += (new_comment,) + return new_comment + + def find_blocks(self, name, exclude=True): # pragma: no cover + return [AugeasBlockNode("CERTBOT_PASS_ASSERT", ancestor=self)] + + def find_directives(self, name, exclude=True): # pragma: no cover + return [AugeasDirectiveNode("CERTBOT_PASS_ASSERT", ancestor=self)] + + def find_comments(self, comment, exact=False): # pragma: no cover + return [AugeasCommentNode("CERTBOT_PASS_ASSERT", ancestor=self)] + + def delete_child(self, child): # pragma: no cover + pass + + def set_parameters(self, parameters): # pragma: no cover + self.parameters = tuple("CERTBOT_PASS_ASSERT") + + def unsaved_files(self): # pragma: no cover + return ["CERTBOT_PASS_ASSERT"] diff --git a/certbot-apache/certbot_apache/configurator.py b/certbot-apache/certbot_apache/configurator.py index ecc7c83ab..7382a4828 100644 --- a/certbot-apache/certbot_apache/configurator.py +++ b/certbot-apache/certbot_apache/configurator.py @@ -29,6 +29,7 @@ from certbot.plugins.util import path_surgery from certbot.plugins.enhancements import AutoHSTSEnhancement from certbot_apache import apache_util +from certbot_apache import augeasparser from certbot_apache import constants from certbot_apache import display_ops from certbot_apache import http_01 @@ -280,6 +281,10 @@ class ApacheConfigurator(common.Installer): "Unable to create a lock file in {0}. Are you running" " Certbot with sufficient privileges to modify your" " Apache configuration?".format(self.option("server_root"))) + + # TODO: apache-parser-v2 + self.parser_root = augeasparser.AugeasBlockNode(None, ancestor=None) + self._prepared = True def save(self, title=None, temporary=False): @@ -507,10 +512,25 @@ class ApacheConfigurator(common.Installer): "cert_key": self.parser.find_dir("SSLCertificateKeyFile", None, vhost.path)} + # TODO: apache-parser-v2 + # We need to add a BlockNode reference to obj.VirtualHost + # v2_path = {"cert_path": vhost.node.find_directives( + # "SSLCertificateFile"), + # "cert_key": vhost.node.find_directives( + # "SSLCertificateKeyFile")} + # parserassert.legacy_assert_dir(path["cert_path"], v2_path["cert_path"]) + # parserassert.legacy_assert_dir(path["cert_key"], v2_path["cert_key"]) + # Only include if a certificate chain is specified if chain_path is not None: path["chain_path"] = self.parser.find_dir( "SSLCertificateChainFile", None, vhost.path) + # TODO: apache-parser-v2 + # v2_path["chain_path"] = vhost.node.find_directives( + # "SSLCertificateChainFile") + # parserassert.legacy_assert_dir(path["chain_path"], + # v2_path["chain_path]) + # Handle errors when certificate/key directives cannot be found if not path["cert_path"]: @@ -535,9 +555,15 @@ class ApacheConfigurator(common.Installer): set_cert_path = cert_path self.parser.aug.set(path["cert_path"][-1], cert_path) self.parser.aug.set(path["cert_key"][-1], key_path) + # TODO: apache-parser-v2 + # path["cert_path"][-1].set_parameters(cert_path,) + # path["cert_key"][-1].set_parameters(key_path,) if chain_path is not None: self.parser.add_dir(vhost.path, "SSLCertificateChainFile", chain_path) + # TODO: apache-parser-v2 + # vhost.node.add_child_directive("SSLCertificateChainFile", + # (chain_path,)) else: raise errors.PluginError("--chain-path is required for your " "version of Apache") @@ -548,6 +574,9 @@ class ApacheConfigurator(common.Installer): set_cert_path = fullchain_path self.parser.aug.set(path["cert_path"][-1], fullchain_path) self.parser.aug.set(path["cert_key"][-1], key_path) + # TODO: apache-parser-v2 + # path["cert_path"][-1].set_parameters(fullchain_path,) + # path["cert_key"][-1].set_parameters(key_path,) # Enable the new vhost if needed if not vhost.enabled: @@ -793,29 +822,48 @@ class ApacheConfigurator(common.Installer): return "" - def _get_vhost_names(self, path): + def _get_vhost_names(self, vhost): """Helper method for getting the ServerName and - ServerAlias values from vhost in path + ServerAlias values from vhost - :param path: Path to read ServerName and ServerAliases from + :param vhost: VirtualHost object to read ServerName and ServerAliases from :returns: Tuple including ServerName and `list` of ServerAlias strings """ servername_match = self.parser.find_dir( - "ServerName", None, start=path, exclude=False) + "ServerName", None, start=vhost.path, exclude=False) serveralias_match = self.parser.find_dir( - "ServerAlias", None, start=path, exclude=False) + "ServerAlias", None, start=vhost.path, exclude=False) + # TODO: apache-parser-v2 + # v2_servername_match = vhost.node.find_directives("ServerName", + # exclude=False) + # v2_serveralias_match = vhost.node.find_directives("ServerAlias", + # exclude=False) + # parserassert.legacy_assert_dir(servername_match, v2_servername_match) + # parserassert.legacy_assert_dir(serveralias_match, v2_serveralias_match) + serveraliases = [] for alias in serveralias_match: serveralias = self.parser.get_arg(alias) serveraliases.append(serveralias) + # TODO: apache-parser-v2 + # v2_serveraliases = [] + # for alias in v2_serveralias_match: + # v2_serveraliases += list(alias.parameters) + # parserassert.legacy_assert_list(serveraliases, v2_serveraliases) + servername = None if servername_match: # Get last ServerName as each overwrites the previous servername = self.parser.get_arg(servername_match[-1]) + # TODO: apache-parser-v2 + # v2_servername = None + # if v2_servername_match: + # v2_servername = v2_servername_match[-1].parameters[-1] + # parserassert.simpleassert(servername, v2_servername) return (servername, serveraliases) @@ -827,7 +875,7 @@ class ApacheConfigurator(common.Installer): """ - servername, serveraliases = self._get_vhost_names(host.path) + servername, serveraliases = self._get_vhost_names(host) for alias in serveraliases: if not host.modmacro: @@ -1476,7 +1524,7 @@ class ApacheConfigurator(common.Installer): def _add_servername_alias(self, target_name, vhost): vh_path = vhost.path - sname, saliases = self._get_vhost_names(vh_path) + sname, saliases = self._get_vhost_names(vhost) if target_name == sname or target_name in saliases: return if self._has_matching_wildcard(vh_path, target_name): diff --git a/certbot-apache/certbot_apache/parserassert.py b/certbot-apache/certbot_apache/parserassert.py index ac4dda77a..0158973eb 100644 --- a/certbot-apache/certbot_apache/parserassert.py +++ b/certbot-apache/certbot_apache/parserassert.py @@ -1,13 +1,28 @@ """Runtime assertions for two different parser implementations""" +def simpleassert(old_value, new_value): + """ + Simple assertion + """ + assert old_value == new_value -def legacy_assert_dir(self, old_result, new_result): +def legacy_assert_list(old_list, new_list): + """ + Used to assert that both of the lists contain the same values. + """ + + assert len(old_list) == len(new_list) + assert all([True for ol in old_list if ol in new_list]) + +def legacy_assert_dir(old_result, new_result): """ Used to test and ensure that the new implementation search results matches the old implementation results. This test is intended to be used only to test the old Augeas implementation results against the ParserNode Augeas implementation. - The returned list is always a list. + This test expects the DirectiveNode to have Augeas path in its attribute dict + "_metadata" with key "augpath". + """ if new_result != "CERTBOT_PASS_ASSERT": @@ -22,12 +37,12 @@ def legacy_assert_dir(self, old_result, new_result): assert len(match) == 1 -def legacy_assert_args(self, old_result, new_result, parser): +def legacy_assert_args(old_result, new_result, parser): """ - Used to test and ensure that returned argument values are the same for + Used to test and ensure that returned parameter values are the same for the old and the new implementation. - Uses ApacheParser to actually fetch the argument for the old result. + Uses ApacheParser to actually fetch the parameter for the old result. This assertion is structured this way because of how parser.get_arg() is currently used in the ApacheConfigurator, making it easier to test the @@ -37,10 +52,10 @@ def legacy_assert_args(self, old_result, new_result, parser): if isinstance(old_result, list): for old in old_result: oldarg = parser.get_arg(old_result) - assert oldarg in new_result.arguments + assert oldarg in new_result.parameters else: oldarg = parser.get_arg(old_result) - assert oldarg in new_result.arguments + assert oldarg in new_result.parameters def assert_dir(first, second): """ @@ -51,7 +66,7 @@ def assert_dir(first, second): return assert first.name == second.name - assert first.arguments == second.arguments + assert first.parameters == second.parameters assert first.dirty == second.dirty @@ -64,6 +79,6 @@ def assert_block(first, second): return assert first.name == second.name - assert first.arguments == second.arguments + assert first.parameters == second.parameters assert len(first.children) == len(second.children) assert first.dirty == second.dirty |