"""
Doveconf - command ``doveconf``
===============================
"""
import string
from insights import parser, add_filter
from insights.core import ConfigParser
from insights.parsr import (EOF, EmptyQuotedString, InSet, Lift, Many, OneLineComment, PosMarker,
QuotedString, skip_none, String, WS, WSChar, LeftCurly, RightCurly, Forward,
EOL)
from insights.parsr.query import Directive, Entry, Section
from insights.specs import Specs
add_filter(Specs.doveconf, [
"{",
"}"
])
[docs]
@parser(Specs.doveconf, continue_on_error=False)
class Doveconf(ConfigParser):
r"""
Class for parsing the ``doveconf`` command.
Sample input::
# 2.2.36 (1f10bfa63): /etc/dovecot/dovecot.conf
auth_anonymous_username = anonymous
auth_cache_negative_ttl = 1 hours
auth_policy_request_attributes = login=%{requested_username} pwhash=%{hashed_password} remote=%{rip} device_id=%{client_id} protocol=%s
auth_policy_server_api_header =
log_timestamp = "%b %d %H:%M:%S "
login_access_sockets =
namespace inbox {
disabled = no
location =
mailbox Drafts {
auto = no
driver =
special_use = \Drafts
}
mailbox Junk {
auto = no
}
order = 0
prefix =
subscriptions = yes
}
passdb {
args =
auth_verbose = default
}
service aggregator {
chroot = .
client_limit = 0
fifo_listener replication-notify-fifo {
group =
mode = 0600
}
group =
unix_listener replication-notify {
mode = 0600
}
user = $default_internal_user
vsz_limit = 18446744073709551615 B
}
valid_chroot_dirs =
verbose_proctitle = no
Example:
>>> doveconf['auth_anonymous_username'].value
'anonymous'
>>> doveconf['auth_cache_negative_ttl'].value
'1 hours'
>>> doveconf['auth_cache_size'].value
'0'
>>> doveconf['auth_policy_request_attributes'].value
'login=%{requested_username} pwhash=%{hashed_password} remote=%{rip} device_id=%{client_id} protocol=%s'
>>> doveconf['log_timestamp'].value
'"%b %d %H:%M:%S "'
>>> doveconf['namespace'][0].value
'inbox'
>>> doveconf['namespace'][0]["mailbox"][1].value
'Junk'
"""
def _parse_doc(self):
def to_directive(name, attrs):
return Directive(name=name.value, attrs=attrs, lineno=name.lineno, src=self)
def to_directive_noval(name, sep):
return Directive(name=name.value, attrs=[], lineno=name.lineno, src=self)
def to_section(name, attrs, body):
return Section(name=name.value, attrs=attrs, children=body, lineno=name.lineno, src=self)
sep_chars = set("=")
Sep = InSet(sep_chars, "Sep")
name_chars = string.ascii_letters + "_/"
Name = Many(WSChar) >> PosMarker(String(name_chars) | EmptyQuotedString(name_chars)) << Many(WSChar)
BareStringDir = String(set(string.printable) - set("\r\n"))
BareStringBlk = String(set(string.printable) - (set(string.whitespace) | set("{}'\"")))
BlockBeg = Many(WSChar) >> LeftCurly << WS
BlockEnd = Many(WSChar) >> RightCurly << (EOL | EOF)
Comment = OneLineComment("#").map(lambda x: None) << (EOL | EOF)
Stmt = Forward()
_AttrDir = Many(WSChar) >> (BareStringDir | QuotedString)
AttrDir = Sep >> Many(_AttrDir)
AttrDirNoVal = Sep << Many(WSChar)
Dir = (Lift(to_directive) * Name * AttrDir) << (EOL | EOF)
DirNoVal = (Lift(to_directive_noval) * Name * AttrDirNoVal) << (EOL | EOF)
_AttrBlk = Many(WSChar) >> (BareStringBlk | QuotedString)
AttrsBlk = Many(_AttrBlk)
BlockBody = BlockBeg >> Many(Stmt).map(skip_none) << BlockEnd
Block = (Lift(to_section) * Name * AttrsBlk * BlockBody)
Stmt <= WS >> (Block | Dir | DirNoVal | Comment) << WS
Doc = Many(Stmt).map(skip_none)
Top = Doc + EOF
return Top
def __init__(self, *args, **kwargs):
self.Top = self._parse_doc()
super(Doveconf, self).__init__(*args, **kwargs)
def parse_doc(self, content):
return Entry(children=self.Top("\n".join(content))[0], src=self)