mirror of
https://github.com/certbot/certbot.git
synced 2026-06-07 15:52:08 -04:00
Merge remote-tracking branch 'origin/apache-parser-v2' into find_ancestors
This commit is contained in:
commit
808fa80c82
5 changed files with 178 additions and 19 deletions
157
certbot-apache/certbot_apache/apacheparser.py
Normal file
157
certbot-apache/certbot_apache/apacheparser.py
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
""" apacheconfig implementation of the ParserNode interfaces """
|
||||
|
||||
from certbot_apache import assertions
|
||||
from certbot_apache import interfaces
|
||||
from certbot_apache import parsernode_util as util
|
||||
|
||||
|
||||
class ApacheParserNode(interfaces.ParserNode):
|
||||
""" apacheconfig implementation of ParserNode interface.
|
||||
|
||||
Expects metadata `ac_ast` to be passed in, where `ac_ast` is the AST provided
|
||||
by parsing the equivalent configuration text using the apacheconfig library.
|
||||
"""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
ancestor, dirty, filepath, metadata = util.parsernode_kwargs(kwargs) # pylint: disable=unused-variable
|
||||
super(ApacheParserNode, self).__init__(**kwargs)
|
||||
self.ancestor = ancestor
|
||||
self.filepath = filepath
|
||||
self.dirty = dirty
|
||||
self.metadata = metadata
|
||||
self._raw = self.metadata["ac_ast"]
|
||||
|
||||
def save(self, msg): # pragma: no cover
|
||||
pass
|
||||
|
||||
|
||||
class ApacheCommentNode(ApacheParserNode):
|
||||
""" apacheconfig implementation of CommentNode interface """
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
comment, kwargs = util.commentnode_kwargs(kwargs) # pylint: disable=unused-variable
|
||||
super(ApacheCommentNode, self).__init__(**kwargs)
|
||||
self.comment = comment
|
||||
|
||||
def __eq__(self, other): # pragma: no cover
|
||||
if isinstance(other, self.__class__):
|
||||
return (self.comment == other.comment and
|
||||
self.dirty == other.dirty and
|
||||
self.ancestor == other.ancestor and
|
||||
self.metadata == other.metadata and
|
||||
self.filepath == other.filepath)
|
||||
return False
|
||||
|
||||
|
||||
class ApacheDirectiveNode(ApacheParserNode):
|
||||
""" apacheconfig implementation of DirectiveNode interface """
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
name, parameters, enabled, kwargs = util.directivenode_kwargs(kwargs)
|
||||
super(ApacheDirectiveNode, self).__init__(**kwargs)
|
||||
self.name = name
|
||||
self.parameters = parameters
|
||||
self.enabled = enabled
|
||||
self.include = None
|
||||
|
||||
def __eq__(self, other): # pragma: no cover
|
||||
if isinstance(other, self.__class__):
|
||||
return (self.name == other.name and
|
||||
self.filepath == other.filepath and
|
||||
self.parameters == other.parameters and
|
||||
self.enabled == other.enabled and
|
||||
self.dirty == other.dirty and
|
||||
self.ancestor == other.ancestor and
|
||||
self.metadata == other.metadata)
|
||||
return False
|
||||
|
||||
def set_parameters(self, parameters):
|
||||
"""Sets the parameters for DirectiveNode"""
|
||||
pass
|
||||
|
||||
|
||||
class ApacheBlockNode(ApacheDirectiveNode):
|
||||
""" apacheconfig implementation of BlockNode interface """
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(ApacheBlockNode, self).__init__(**kwargs)
|
||||
self.children = ()
|
||||
|
||||
def __eq__(self, other): # pragma: no cover
|
||||
if isinstance(other, self.__class__):
|
||||
return (self.name == other.name and
|
||||
self.filepath == other.filepath and
|
||||
self.parameters == other.parameters and
|
||||
self.children == other.children and
|
||||
self.enabled == other.enabled and
|
||||
self.dirty == other.dirty and
|
||||
self.ancestor == other.ancestor and
|
||||
self.metadata == other.metadata)
|
||||
return False
|
||||
|
||||
def add_child_block(self, name, parameters=None, position=None): # pylint: disable=unused-argument
|
||||
"""Adds a new BlockNode to the sequence of children"""
|
||||
new_block = ApacheBlockNode(name=assertions.PASS,
|
||||
parameters=assertions.PASS,
|
||||
ancestor=self,
|
||||
filepath=assertions.PASS,
|
||||
metadata=self.metadata)
|
||||
self.children += (new_block,)
|
||||
return new_block
|
||||
|
||||
def add_child_directive(self, name, parameters=None, position=None): # pylint: disable=unused-argument
|
||||
"""Adds a new DirectiveNode to the sequence of children"""
|
||||
new_dir = ApacheDirectiveNode(name=assertions.PASS,
|
||||
parameters=assertions.PASS,
|
||||
ancestor=self,
|
||||
filepath=assertions.PASS,
|
||||
metadata=self.metadata)
|
||||
self.children += (new_dir,)
|
||||
return new_dir
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
def add_child_comment(self, comment="", position=None): # pragma: no cover
|
||||
|
||||
"""Adds a new CommentNode to the sequence of children"""
|
||||
new_comment = ApacheCommentNode(comment=assertions.PASS,
|
||||
ancestor=self,
|
||||
filepath=assertions.PASS,
|
||||
metadata=self.metadata)
|
||||
self.children += (new_comment,)
|
||||
return new_comment
|
||||
|
||||
def find_blocks(self, name, exclude=True): # pylint: disable=unused-argument
|
||||
"""Recursive search of BlockNodes from the sequence of children"""
|
||||
return [ApacheBlockNode(name=assertions.PASS,
|
||||
parameters=assertions.PASS,
|
||||
ancestor=self,
|
||||
filepath=assertions.PASS,
|
||||
metadata=self.metadata)]
|
||||
|
||||
def find_directives(self, name, exclude=True): # pylint: disable=unused-argument
|
||||
"""Recursive search of DirectiveNodes from the sequence of children"""
|
||||
return [ApacheDirectiveNode(name=assertions.PASS,
|
||||
parameters=assertions.PASS,
|
||||
ancestor=self,
|
||||
filepath=assertions.PASS,
|
||||
metadata=self.metadata)]
|
||||
|
||||
def find_comments(self, comment, exact=False): # pylint: disable=unused-argument
|
||||
"""Recursive search of DirectiveNodes from the sequence of children"""
|
||||
return [ApacheCommentNode(comment=assertions.PASS,
|
||||
ancestor=self,
|
||||
filepath=assertions.PASS,
|
||||
metadata=self.metadata)]
|
||||
|
||||
def delete_child(self, child): # pragma: no cover
|
||||
"""Deletes a ParserNode from the sequence of children"""
|
||||
pass
|
||||
|
||||
def unsaved_files(self): # pragma: no cover
|
||||
"""Returns a list of unsaved filepaths"""
|
||||
return [assertions.PASS]
|
||||
|
||||
|
||||
interfaces.CommentNode.register(ApacheCommentNode)
|
||||
interfaces.DirectiveNode.register(ApacheDirectiveNode)
|
||||
interfaces.BlockNode.register(ApacheBlockNode)
|
||||
|
|
@ -258,7 +258,8 @@ class ApacheConfigurator(common.Installer):
|
|||
|
||||
# Set up ParserNode root
|
||||
pn_meta = {"augeasparser": self.parser,
|
||||
"augeaspath": self.parser.get_root_augpath()}
|
||||
"augeaspath": self.parser.get_root_augpath(),
|
||||
"ac_ast": None}
|
||||
self.parser_root = self.get_parsernode_root(pn_meta)
|
||||
|
||||
# Check for errors in parsing files with Augeas
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
""" Dual ParserNode implementation """
|
||||
from certbot_apache import assertions
|
||||
from certbot_apache import augeasparser
|
||||
from certbot_apache import apacheparser
|
||||
|
||||
|
||||
class DualNodeBase(object):
|
||||
|
|
@ -57,7 +58,7 @@ class DualCommentNode(DualNodeBase):
|
|||
self.secondary = secondary
|
||||
else:
|
||||
self.primary = augeasparser.AugeasCommentNode(**kwargs)
|
||||
self.secondary = augeasparser.AugeasCommentNode(**kwargs)
|
||||
self.secondary = apacheparser.ApacheCommentNode(**kwargs)
|
||||
|
||||
assertions.assertEqual(self.primary, self.secondary)
|
||||
|
||||
|
|
@ -91,7 +92,7 @@ class DualDirectiveNode(DualNodeBase):
|
|||
self.secondary = secondary
|
||||
else:
|
||||
self.primary = augeasparser.AugeasDirectiveNode(**kwargs)
|
||||
self.secondary = augeasparser.AugeasDirectiveNode(**kwargs)
|
||||
self.secondary = apacheparser.ApacheDirectiveNode(**kwargs)
|
||||
|
||||
assertions.assertEqual(self.primary, self.secondary)
|
||||
|
||||
|
|
@ -131,7 +132,7 @@ class DualBlockNode(DualNodeBase):
|
|||
self.secondary = secondary
|
||||
else:
|
||||
self.primary = augeasparser.AugeasBlockNode(**kwargs)
|
||||
self.secondary = augeasparser.AugeasBlockNode(**kwargs)
|
||||
self.secondary = apacheparser.ApacheBlockNode(**kwargs)
|
||||
|
||||
assertions.assertEqual(self.primary, self.secondary)
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ class AugeasParserNodeTest(util.ApacheTest): # pylint: disable=too-many-public-
|
|||
name=servernames[0].name,
|
||||
parameters=["test", "setting", "these"],
|
||||
ancestor=assertions.PASS,
|
||||
metadata=servernames[0].metadata
|
||||
metadata=servernames[0].primary.metadata
|
||||
)
|
||||
self.assertTrue(mock_set.called)
|
||||
self.assertEqual(
|
||||
|
|
@ -145,11 +145,11 @@ class AugeasParserNodeTest(util.ApacheTest): # pylint: disable=too-many-public-
|
|||
self.assertTrue(found)
|
||||
|
||||
def test_delete_child(self):
|
||||
listens = self.config.parser_root.find_directives("Listen")
|
||||
listens = self.config.parser_root.primary.find_directives("Listen")
|
||||
self.assertEqual(len(listens), 1)
|
||||
self.config.parser_root.primary.delete_child(listens[0])
|
||||
|
||||
listens = self.config.parser_root.find_directives("Listen")
|
||||
listens = self.config.parser_root.primary.find_directives("Listen")
|
||||
self.assertEqual(len(listens), 0)
|
||||
|
||||
def test_delete_child_not_found(self):
|
||||
|
|
@ -163,11 +163,11 @@ class AugeasParserNodeTest(util.ApacheTest): # pylint: disable=too-many-public-
|
|||
)
|
||||
|
||||
def test_add_child_block(self):
|
||||
nb = self.config.parser_root.primary.add_child_block(
|
||||
nb = self.config.parser_root.add_child_block(
|
||||
"NewBlock",
|
||||
["first", "second"]
|
||||
)
|
||||
rpath, _, directive = nb.metadata["augeaspath"].rpartition("/")
|
||||
rpath, _, directive = nb.primary.metadata["augeaspath"].rpartition("/")
|
||||
self.assertEqual(
|
||||
rpath,
|
||||
self.config.parser_root.primary.metadata["augeaspath"]
|
||||
|
|
@ -175,7 +175,7 @@ class AugeasParserNodeTest(util.ApacheTest): # pylint: disable=too-many-public-
|
|||
self.assertTrue(directive.startswith("NewBlock"))
|
||||
|
||||
def test_add_child_block_beginning(self):
|
||||
self.config.parser_root.primary.add_child_block(
|
||||
self.config.parser_root.add_child_block(
|
||||
"Beginning",
|
||||
position=0
|
||||
)
|
||||
|
|
@ -186,7 +186,7 @@ class AugeasParserNodeTest(util.ApacheTest): # pylint: disable=too-many-public-
|
|||
self.assertTrue(first[0].endswith("Beginning"))
|
||||
|
||||
def test_add_child_block_append(self):
|
||||
self.config.parser_root.primary.add_child_block(
|
||||
self.config.parser_root.add_child_block(
|
||||
"VeryLast",
|
||||
)
|
||||
parser = self.config.parser_root.primary.parser
|
||||
|
|
@ -196,7 +196,7 @@ class AugeasParserNodeTest(util.ApacheTest): # pylint: disable=too-many-public-
|
|||
self.assertTrue(last[0].endswith("VeryLast"))
|
||||
|
||||
def test_add_child_block_append_alt(self):
|
||||
self.config.parser_root.primary.add_child_block(
|
||||
self.config.parser_root.add_child_block(
|
||||
"VeryLastAlt",
|
||||
position=99999
|
||||
)
|
||||
|
|
@ -207,7 +207,7 @@ class AugeasParserNodeTest(util.ApacheTest): # pylint: disable=too-many-public-
|
|||
self.assertTrue(last[0].endswith("VeryLastAlt"))
|
||||
|
||||
def test_add_child_block_middle(self):
|
||||
self.config.parser_root.primary.add_child_block(
|
||||
self.config.parser_root.add_child_block(
|
||||
"Middle",
|
||||
position=5
|
||||
)
|
||||
|
|
@ -223,12 +223,12 @@ class AugeasParserNodeTest(util.ApacheTest): # pylint: disable=too-many-public-
|
|||
# There already exists a single VirtualHost in the base config
|
||||
new_block = parser.aug.match("{}/VirtualHost[2]".format(root_path))
|
||||
self.assertEqual(len(new_block), 0)
|
||||
vh = self.config.parser_root.primary.add_child_block(
|
||||
vh = self.config.parser_root.add_child_block(
|
||||
"VirtualHost",
|
||||
)
|
||||
new_block = parser.aug.match("{}/VirtualHost[2]".format(root_path))
|
||||
self.assertEqual(len(new_block), 1)
|
||||
self.assertTrue(vh.metadata["augeaspath"].endswith("VirtualHost[2]"))
|
||||
self.assertTrue(vh.primary.metadata["augeaspath"].endswith("VirtualHost[2]"))
|
||||
|
||||
def test_node_init_error_bad_augeaspath(self):
|
||||
from certbot_apache.augeasparser import AugeasBlockNode
|
||||
|
|
@ -264,7 +264,7 @@ class AugeasParserNodeTest(util.ApacheTest): # pylint: disable=too-many-public-
|
|||
)
|
||||
|
||||
def test_add_child_directive(self):
|
||||
self.config.parser_root.primary.add_child_directive(
|
||||
self.config.parser_root.add_child_directive(
|
||||
"ThisWasAdded",
|
||||
["with", "parameters"],
|
||||
position=0
|
||||
|
|
@ -273,12 +273,12 @@ class AugeasParserNodeTest(util.ApacheTest): # pylint: disable=too-many-public-
|
|||
self.assertEqual(len(dirs), 1)
|
||||
self.assertEqual(dirs[0].parameters, ("with", "parameters"))
|
||||
# The new directive was added to the very first line of the config
|
||||
self.assertTrue(dirs[0].metadata["augeaspath"].endswith("[1]"))
|
||||
self.assertTrue(dirs[0].primary.metadata["augeaspath"].endswith("[1]"))
|
||||
|
||||
def test_add_child_directive_exception(self):
|
||||
self.assertRaises(
|
||||
errors.PluginError,
|
||||
self.config.parser_root.primary.add_child_directive,
|
||||
self.config.parser_root.add_child_directive,
|
||||
"ThisRaisesErrorBecauseMissingParameters"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ class DualParserNodeTest(unittest.TestCase): # pylint: disable=too-many-public-
|
|||
parser_mock = mock.MagicMock()
|
||||
parser_mock.aug.match.return_value = []
|
||||
parser_mock.get_arg.return_value = []
|
||||
self.metadata = {"augeasparser": parser_mock, "augeaspath": "/invalid"}
|
||||
self.metadata = {"augeasparser": parser_mock, "augeaspath": "/invalid", "ac_ast": None}
|
||||
self.block = dualparser.DualBlockNode(name="block",
|
||||
ancestor=None,
|
||||
filepath="/tmp/something",
|
||||
|
|
|
|||
Loading…
Reference in a new issue