rename config option args to options
This commit is contained in:
@@ -97,7 +97,7 @@ def list_quarantines(quarantines, args):
|
|||||||
else:
|
else:
|
||||||
qlist = []
|
qlist = []
|
||||||
for q in quarantines:
|
for q in quarantines:
|
||||||
cfg = q["args"]
|
cfg = q["options"]
|
||||||
storage_type = cfg["store"]["type"]
|
storage_type = cfg["store"]["type"]
|
||||||
|
|
||||||
if "notify" in cfg:
|
if "notify" in cfg:
|
||||||
|
|||||||
@@ -269,7 +269,7 @@ class ActionConfig(BaseConfig):
|
|||||||
|
|
||||||
JSON_SCHEMA = {
|
JSON_SCHEMA = {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": ["name", "type", "args"],
|
"required": ["name", "type", "options"],
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
"properties": {
|
"properties": {
|
||||||
"name": {"type": "string"},
|
"name": {"type": "string"},
|
||||||
@@ -277,14 +277,14 @@ class ActionConfig(BaseConfig):
|
|||||||
"pretend": {"type": "boolean", "default": False},
|
"pretend": {"type": "boolean", "default": False},
|
||||||
"conditions": {"type": "object"},
|
"conditions": {"type": "object"},
|
||||||
"type": {"enum": list(ACTION_TYPES.keys())},
|
"type": {"enum": list(ACTION_TYPES.keys())},
|
||||||
"args": {"type": "object"}}}
|
"options": {"type": "object"}}}
|
||||||
|
|
||||||
def __init__(self, config, rec=True):
|
def __init__(self, config, rec=True):
|
||||||
super().__init__(config)
|
super().__init__(config)
|
||||||
if rec:
|
if rec:
|
||||||
if "conditions" in self:
|
if "conditions" in self:
|
||||||
self["conditions"] = ConditionsConfig(self["conditions"])
|
self["conditions"] = ConditionsConfig(self["conditions"])
|
||||||
self["action"] = self.ACTION_TYPES[self["type"]](self["args"])
|
self["action"] = self.ACTION_TYPES[self["type"]](self["options"])
|
||||||
|
|
||||||
|
|
||||||
class RuleConfig(BaseConfig):
|
class RuleConfig(BaseConfig):
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
# Section: conditions
|
# Section: conditions
|
||||||
# Notes: Optional conditions to process the rule.
|
# Notes: Optional conditions to process the rule.
|
||||||
# If multiple conditions are set, they all
|
# If multiple conditions are set, they all
|
||||||
# have to be true to process the rule.
|
# have to be true for the rule to be processed.
|
||||||
#
|
#
|
||||||
"conditions": {
|
"conditions": {
|
||||||
# Option: local
|
# Option: local
|
||||||
|
|||||||
221
pyquarantine/misc/pyquarantine.conf.example_old
Normal file
221
pyquarantine/misc/pyquarantine.conf.example_old
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
# This is an example /etc/pyquarantine/pyquarantine.conf file.
|
||||||
|
# Copy it into place before use.
|
||||||
|
#
|
||||||
|
# The file is in JSON format.
|
||||||
|
#
|
||||||
|
# The global option 'log' can be overriden per rule or per modification.
|
||||||
|
#
|
||||||
|
{
|
||||||
|
# Section: global
|
||||||
|
# Notes: Global options.
|
||||||
|
#
|
||||||
|
"global": {
|
||||||
|
# Option: socket
|
||||||
|
# Type: String
|
||||||
|
# Notes: The socket used to communicate with the MTA.
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
# unix:/path/to/socket a named pipe
|
||||||
|
# inet:8899 listen on ANY interface
|
||||||
|
# inet:8899@localhost listen on a specific interface
|
||||||
|
# inet6:8899 listen on ANY interface
|
||||||
|
# inet6:8899@[2001:db8:1234::1] listen on a specific interface
|
||||||
|
# Value: [ SOCKET ]
|
||||||
|
"socket": "inet:8898@127.0.0.1",
|
||||||
|
|
||||||
|
# Option: local_addrs
|
||||||
|
# Type: List
|
||||||
|
# Notes: A list of local hosts and networks.
|
||||||
|
# Value: [ LIST ]
|
||||||
|
#
|
||||||
|
"local_addrs": ["fe80::/64", "::1/128", "127.0.0.0/8", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"],
|
||||||
|
|
||||||
|
# Option: loglevel
|
||||||
|
# Type: String
|
||||||
|
# Notes: Set loglevel for rules and actions.
|
||||||
|
# Value: [ error | warning | info | debug ]
|
||||||
|
#
|
||||||
|
"loglevel": "info",
|
||||||
|
|
||||||
|
# Option: pretend
|
||||||
|
# Type: Bool
|
||||||
|
# Notes: Just pretend to do the actions, for test purposes.
|
||||||
|
# Value: [ true | false ]
|
||||||
|
#
|
||||||
|
"pretend": true
|
||||||
|
},
|
||||||
|
|
||||||
|
# Section: rules
|
||||||
|
# Notes: Rules and related actions.
|
||||||
|
#
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
# Option: name
|
||||||
|
# Type: String
|
||||||
|
# Notes: Name of the rule.
|
||||||
|
# Value: [ NAME ]
|
||||||
|
#
|
||||||
|
"name": "myrule",
|
||||||
|
|
||||||
|
# Section: conditions
|
||||||
|
# Notes: Optional conditions to process the rule.
|
||||||
|
# If multiple conditions are set, they all
|
||||||
|
# have to be true to process the rule.
|
||||||
|
#
|
||||||
|
"conditions": {
|
||||||
|
# Option: local
|
||||||
|
# Type: Bool
|
||||||
|
# Notes: Condition wheter the senders host address is listed in local_addrs.
|
||||||
|
# Value: [ true | false ]
|
||||||
|
#
|
||||||
|
"local": false,
|
||||||
|
|
||||||
|
# Option: hosts
|
||||||
|
# Type: String
|
||||||
|
# Notes: Condition wheter the senders host address is listed in this list.
|
||||||
|
# Value: [ LIST ]
|
||||||
|
#
|
||||||
|
"hosts": [ "127.0.0.1" ],
|
||||||
|
|
||||||
|
# Option: envfrom
|
||||||
|
# Type: String
|
||||||
|
# Notes: Condition wheter the envelop-from address matches this regular expression.
|
||||||
|
# Value: [ REGEX ]
|
||||||
|
#
|
||||||
|
"envfrom": "^.+@mypartner\\.com$",
|
||||||
|
|
||||||
|
# Option: envto
|
||||||
|
# Type: String
|
||||||
|
# Notes: Condition wheter the envelop-to address matches this regular expression.
|
||||||
|
# Value: [ REGEX ]
|
||||||
|
#
|
||||||
|
"envto": "^postmaster@.+$"
|
||||||
|
},
|
||||||
|
|
||||||
|
# Section: actions
|
||||||
|
# Notes: Actions of the rule.
|
||||||
|
#
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
# Option: name
|
||||||
|
# Type: String
|
||||||
|
# Notes: Name of the modification.
|
||||||
|
# Value: [ NAME ]
|
||||||
|
#
|
||||||
|
"name": "add_test_header",
|
||||||
|
|
||||||
|
# Option: type
|
||||||
|
# Type: String
|
||||||
|
# Notes: Type of the modification.
|
||||||
|
# Value: [ add_header | del_header | mod_header ]
|
||||||
|
#
|
||||||
|
"type": "add_header",
|
||||||
|
|
||||||
|
# Option: field
|
||||||
|
# Type: String
|
||||||
|
# Notes: Name of the header.
|
||||||
|
# Value: [ NAME ]
|
||||||
|
#
|
||||||
|
"field": "X-Test-Header",
|
||||||
|
|
||||||
|
# Option: value
|
||||||
|
# Type: String
|
||||||
|
# Notes: Value of the header.
|
||||||
|
# Value: [ VALUE ]
|
||||||
|
#
|
||||||
|
"value": "true"
|
||||||
|
}, {
|
||||||
|
"name": "modify_subject",
|
||||||
|
|
||||||
|
"type": "mod_header",
|
||||||
|
|
||||||
|
# Option: field
|
||||||
|
# Type: String
|
||||||
|
# Notes: Regular expression to match against header lines (e.g. Subject: Test-Subject).
|
||||||
|
# Value: [ REGEX ]
|
||||||
|
#
|
||||||
|
"field": "^Subject$",
|
||||||
|
|
||||||
|
# Option: search
|
||||||
|
# Type: String
|
||||||
|
# Notes: Regular expression to match against the headers value.
|
||||||
|
# Values: [ VALUE ]
|
||||||
|
#
|
||||||
|
"search": "(?P<subject>.*)",
|
||||||
|
|
||||||
|
# Option: value
|
||||||
|
# Type: String
|
||||||
|
# Notes: New value of the header.
|
||||||
|
# Values: [ VALUE ]
|
||||||
|
"value": "[EXTERNAL] \\g<subject>"
|
||||||
|
}, {
|
||||||
|
"name": "delete_received_header",
|
||||||
|
|
||||||
|
"type": "del_header",
|
||||||
|
|
||||||
|
# Option: field
|
||||||
|
# Type: String
|
||||||
|
# Notes: Regular expression to match against header lines (e.g. Subject: Test-Subject).
|
||||||
|
# Value: [ REGEX ]
|
||||||
|
#
|
||||||
|
"field": "^Received$"
|
||||||
|
}, {
|
||||||
|
"name": "add_disclaimer",
|
||||||
|
|
||||||
|
"type": "add_disclaimer",
|
||||||
|
|
||||||
|
# Option: action
|
||||||
|
# Type: String
|
||||||
|
# Notes: Action to perform with the disclaimer.
|
||||||
|
# Value: [ append | prepend ]
|
||||||
|
#
|
||||||
|
"action": "prepend",
|
||||||
|
|
||||||
|
# Option: html_template
|
||||||
|
# Type: String
|
||||||
|
# Notes: Path to a file which contains the html representation of the disclaimer.
|
||||||
|
# Value: [ FILE_PATH ]
|
||||||
|
#
|
||||||
|
"html_template": "/etc/pyquarantine/templates/disclaimer_html.template",
|
||||||
|
|
||||||
|
# Option: text_template
|
||||||
|
# Type: String
|
||||||
|
# Notes: Path to a file which contains the text representation of the disclaimer.
|
||||||
|
# Value: [ FILE_PATH ]
|
||||||
|
#
|
||||||
|
"text_template": "/etc/pyquarantine/templates/disclaimer_text.template",
|
||||||
|
|
||||||
|
# Option: error_policy
|
||||||
|
# Type: String
|
||||||
|
# Notes: Set what should be done if the modification fails (e.g. no message body present).
|
||||||
|
# Value: [ wrap | ignore | reject ]
|
||||||
|
#
|
||||||
|
"error_policy": "wrap"
|
||||||
|
}, {
|
||||||
|
"name": "store_message",
|
||||||
|
|
||||||
|
"type": "store",
|
||||||
|
|
||||||
|
# Option: storage_type
|
||||||
|
# Type: String
|
||||||
|
# Notes: The storage type used to store e-mails.
|
||||||
|
# Value: [ file ]
|
||||||
|
"storage_type": "file",
|
||||||
|
|
||||||
|
# Option: directory
|
||||||
|
# Type: String
|
||||||
|
# Notes: Directory used to store e-mails.
|
||||||
|
# Value: [ file ]
|
||||||
|
"directory": "/mnt/messages",
|
||||||
|
|
||||||
|
# Option: original
|
||||||
|
# Type: Bool
|
||||||
|
# Notes: If set to true, store the message as received by the MTA instead of storing the current state
|
||||||
|
# of the message, that may was modified already by other actions.
|
||||||
|
# Value: [ true | false ]
|
||||||
|
"original": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -390,14 +390,14 @@ class Modify:
|
|||||||
self.cfg = cfg
|
self.cfg = cfg
|
||||||
self.logger = logging.getLogger(cfg["name"])
|
self.logger = logging.getLogger(cfg["name"])
|
||||||
self.logger.setLevel(cfg.get_loglevel(debug))
|
self.logger.setLevel(cfg.get_loglevel(debug))
|
||||||
cfg["args"]["pretend"] = cfg["pretend"]
|
cfg["options"]["pretend"] = cfg["pretend"]
|
||||||
self._modification = self.MODIFICATION_TYPES[cfg["type"]](
|
self._modification = self.MODIFICATION_TYPES[cfg["type"]](
|
||||||
**cfg["args"])
|
**cfg["options"])
|
||||||
self._headersonly = self._modification._headersonly
|
self._headersonly = self._modification._headersonly
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
cfg = []
|
cfg = []
|
||||||
for key, value in self.cfg["args"].items():
|
for key, value in self.cfg["options"].items():
|
||||||
cfg.append(f"{key}={value}")
|
cfg.append(f"{key}={value}")
|
||||||
class_name = type(self._modification).__name__
|
class_name = type(self._modification).__name__
|
||||||
return f"{class_name}(" + ", ".join(cfg) + ")"
|
return f"{class_name}(" + ", ".join(cfg) + ")"
|
||||||
|
|||||||
@@ -332,16 +332,16 @@ class Notify:
|
|||||||
self.logger = logging.getLogger(cfg["name"])
|
self.logger = logging.getLogger(cfg["name"])
|
||||||
self.logger.setLevel(cfg.get_loglevel(debug))
|
self.logger.setLevel(cfg.get_loglevel(debug))
|
||||||
|
|
||||||
nodification_type = cfg["args"]["type"]
|
nodification_type = cfg["options"]["type"]
|
||||||
del cfg["args"]["type"]
|
del cfg["options"]["type"]
|
||||||
cfg["args"]["pretend"] = cfg["pretend"]
|
cfg["options"]["pretend"] = cfg["pretend"]
|
||||||
self._notification = self.NOTIFICATION_TYPES[nodification_type](
|
self._notification = self.NOTIFICATION_TYPES[nodification_type](
|
||||||
**cfg["args"])
|
**cfg["options"])
|
||||||
self._headersonly = self._notification._headersonly
|
self._headersonly = self._notification._headersonly
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
cfg = []
|
cfg = []
|
||||||
for key, value in self.cfg["args"].items():
|
for key, value in self.cfg["options"].items():
|
||||||
cfg.append(f"{key}={value}")
|
cfg.append(f"{key}={value}")
|
||||||
class_name = type(self._notification).__name__
|
class_name = type(self._notification).__name__
|
||||||
return f"{class_name}(" + ", ".join(cfg) + ")"
|
return f"{class_name}(" + ", ".join(cfg) + ")"
|
||||||
|
|||||||
@@ -375,16 +375,16 @@ class Store:
|
|||||||
self.logger = logging.getLogger(cfg["name"])
|
self.logger = logging.getLogger(cfg["name"])
|
||||||
self.logger.setLevel(cfg.get_loglevel(debug))
|
self.logger.setLevel(cfg.get_loglevel(debug))
|
||||||
|
|
||||||
storage_type = cfg["args"]["type"]
|
storage_type = cfg["options"]["type"]
|
||||||
del cfg["args"]["type"]
|
del cfg["options"]["type"]
|
||||||
cfg["args"]["pretend"] = cfg["pretend"]
|
cfg["options"]["pretend"] = cfg["pretend"]
|
||||||
self._storage = self.STORAGE_TYPES[storage_type](
|
self._storage = self.STORAGE_TYPES[storage_type](
|
||||||
**cfg["args"])
|
**cfg["options"])
|
||||||
self._headersonly = self._storage._headersonly
|
self._headersonly = self._storage._headersonly
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
cfg = []
|
cfg = []
|
||||||
for key, value in self.cfg["args"].items():
|
for key, value in self.cfg["options"].items():
|
||||||
cfg.append(f"{key}={value}")
|
cfg.append(f"{key}={value}")
|
||||||
class_name = type(self._storage).__name__
|
class_name = type(self._storage).__name__
|
||||||
return f"{class_name}(" + ", ".join(cfg) + ")"
|
return f"{class_name}(" + ", ".join(cfg) + ")"
|
||||||
@@ -412,25 +412,25 @@ class Quarantine:
|
|||||||
"loglevel": cfg["loglevel"],
|
"loglevel": cfg["loglevel"],
|
||||||
"pretend": cfg["pretend"],
|
"pretend": cfg["pretend"],
|
||||||
"type": "store",
|
"type": "store",
|
||||||
"args": cfg["args"]["store"].get_config()})
|
"options": cfg["options"]["store"].get_config()})
|
||||||
self._storage = Store(storage_cfg, local_addrs, debug)
|
self._storage = Store(storage_cfg, local_addrs, debug)
|
||||||
|
|
||||||
self.smtp_host = cfg["args"]["smtp_host"]
|
self.smtp_host = cfg["options"]["smtp_host"]
|
||||||
self.smtp_port = cfg["args"]["smtp_port"]
|
self.smtp_port = cfg["options"]["smtp_port"]
|
||||||
|
|
||||||
self._notification = None
|
self._notification = None
|
||||||
if "notify" in cfg["args"]:
|
if "notify" in cfg["options"]:
|
||||||
notify_cfg = ActionConfig({
|
notify_cfg = ActionConfig({
|
||||||
"name": cfg["name"],
|
"name": cfg["name"],
|
||||||
"loglevel": cfg["loglevel"],
|
"loglevel": cfg["loglevel"],
|
||||||
"pretend": cfg["pretend"],
|
"pretend": cfg["pretend"],
|
||||||
"type": "notify",
|
"type": "notify",
|
||||||
"args": cfg["args"]["notify"].get_config()})
|
"options": cfg["options"]["notify"].get_config()})
|
||||||
self._notification = Notify(notify_cfg, local_addrs, debug)
|
self._notification = Notify(notify_cfg, local_addrs, debug)
|
||||||
|
|
||||||
self._whitelist = None
|
self._whitelist = None
|
||||||
if "whitelist" in cfg["args"]:
|
if "whitelist" in cfg["options"]:
|
||||||
whitelist_cfg = cfg["args"]["whitelist"]
|
whitelist_cfg = cfg["options"]["whitelist"]
|
||||||
whitelist_cfg["name"] = cfg["name"]
|
whitelist_cfg["name"] = cfg["name"]
|
||||||
whitelist_cfg["loglevel"] = cfg["loglevel"]
|
whitelist_cfg["loglevel"] = cfg["loglevel"]
|
||||||
self._whitelist = Conditions(
|
self._whitelist = Conditions(
|
||||||
@@ -439,15 +439,15 @@ class Quarantine:
|
|||||||
debug=debug)
|
debug=debug)
|
||||||
|
|
||||||
self._milter_action = None
|
self._milter_action = None
|
||||||
if "milter_action" in cfg["args"]:
|
if "milter_action" in cfg["options"]:
|
||||||
self._milter_action = cfg["args"]["milter_action"].upper()
|
self._milter_action = cfg["options"]["milter_action"].upper()
|
||||||
assert self._milter_action in ["ACCEPT", "REJECT", "DISCARD"], \
|
assert self._milter_action in ["ACCEPT", "REJECT", "DISCARD"], \
|
||||||
f"invalid milter_action '{cfg['args']['milter_action']}'"
|
f"invalid milter_action '{cfg['args']['milter_action']}'"
|
||||||
|
|
||||||
self._reason = None
|
self._reason = None
|
||||||
if self._milter_action == "REJECT":
|
if self._milter_action == "REJECT":
|
||||||
if "reject_reason" in cfg["args"]:
|
if "reject_reason" in cfg["options"]:
|
||||||
self._reason = cfg["args"]["reject_reason"]
|
self._reason = cfg["options"]["reject_reason"]
|
||||||
else:
|
else:
|
||||||
self._reason = "Message rejected"
|
self._reason = "Message rejected"
|
||||||
|
|
||||||
@@ -459,9 +459,9 @@ class Quarantine:
|
|||||||
if self._whitelist is not None:
|
if self._whitelist is not None:
|
||||||
cfg.append(f"whitelist={str(self._whitelist)}")
|
cfg.append(f"whitelist={str(self._whitelist)}")
|
||||||
for key in ["milter_action", "reject_reason"]:
|
for key in ["milter_action", "reject_reason"]:
|
||||||
if key not in self.cfg["args"]:
|
if key not in self.cfg["options"]:
|
||||||
continue
|
continue
|
||||||
value = self.cfg["args"][key]
|
value = self.cfg["options"][key]
|
||||||
cfg.append(f"{key}={value}")
|
cfg.append(f"{key}={value}")
|
||||||
class_name = type(self).__name__
|
class_name = type(self).__name__
|
||||||
return f"{class_name}(" + ", ".join(cfg) + ")"
|
return f"{class_name}(" + ", ".join(cfg) + ")"
|
||||||
|
|||||||
Reference in New Issue
Block a user