mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2026-05-27 01:41:58 +00:00
[DockerApi] Rename DockerApi to Controller and add mailcow-adm tool
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
from modules.Sogo import Sogo
|
||||
from models.BaseModel import BaseModel
|
||||
|
||||
class AddressbookModel(BaseModel):
|
||||
parser_command = "addressbook"
|
||||
required_args = {
|
||||
"add": [["username", "name"]],
|
||||
"delete": [["username", "name"]],
|
||||
"get": [["username", "name"]],
|
||||
"set_acl": [["username", "name", "sharee_email", "acl"]],
|
||||
"get_acl": [["username", "name"]],
|
||||
"delete_acl": [["username", "name", "sharee_email"]],
|
||||
"add_contact": [["username", "name", "contact_name", "contact_email", "type"]],
|
||||
"delete_contact": [["username", "name", "contact_name"]],
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
username=None,
|
||||
name=None,
|
||||
sharee_email=None,
|
||||
acl=None,
|
||||
subscribe=None,
|
||||
ics=None,
|
||||
contact_name=None,
|
||||
contact_email=None,
|
||||
type=None,
|
||||
**kwargs
|
||||
):
|
||||
self.sogo = Sogo(username)
|
||||
|
||||
self.name = name
|
||||
self.acl = acl
|
||||
self.sharee_email = sharee_email
|
||||
self.subscribe = subscribe
|
||||
self.ics = ics
|
||||
self.contact_name = contact_name
|
||||
self.contact_email = contact_email
|
||||
self.type = type
|
||||
|
||||
def add(self):
|
||||
"""
|
||||
Add a new addressbook.
|
||||
:return: Response from SOGo API.
|
||||
"""
|
||||
return self.sogo.addAddressbook(self.name)
|
||||
|
||||
def set_acl(self):
|
||||
"""
|
||||
Set ACL for the addressbook.
|
||||
:return: Response from SOGo API.
|
||||
"""
|
||||
addressbook_id = self.sogo.getAddressbookIdByName(self.name)
|
||||
if not addressbook_id:
|
||||
print(f"Addressbook '{self.name}' not found for user '{self.username}'.")
|
||||
return None
|
||||
return self.sogo.setAddressbookACL(addressbook_id, self.sharee_email, self.acl, self.subscribe)
|
||||
|
||||
def delete_acl(self):
|
||||
"""
|
||||
Delete the addressbook ACL.
|
||||
:return: Response from SOGo API.
|
||||
"""
|
||||
addressbook_id = self.sogo.getAddressbookIdByName(self.name)
|
||||
if not addressbook_id:
|
||||
print(f"Addressbook '{self.name}' not found for user '{self.username}'.")
|
||||
return None
|
||||
return self.sogo.deleteAddressbookACL(addressbook_id, self.sharee_email)
|
||||
|
||||
def get_acl(self):
|
||||
"""
|
||||
Get the ACL for the addressbook.
|
||||
:return: Response from SOGo API.
|
||||
"""
|
||||
addressbook_id = self.sogo.getAddressbookIdByName(self.name)
|
||||
if not addressbook_id:
|
||||
print(f"Addressbook '{self.name}' not found for user '{self.username}'.")
|
||||
return None
|
||||
return self.sogo.getAddressbookACL(addressbook_id)
|
||||
|
||||
def add_contact(self):
|
||||
"""
|
||||
Add a new contact to the addressbook.
|
||||
:return: Response from SOGo API.
|
||||
"""
|
||||
addressbook_id = self.sogo.getAddressbookIdByName(self.name)
|
||||
if not addressbook_id:
|
||||
print(f"Addressbook '{self.name}' not found for user '{self.username}'.")
|
||||
return None
|
||||
if self.type == "card":
|
||||
return self.sogo.addAddressbookContact(addressbook_id, self.contact_name, self.contact_email)
|
||||
elif self.type == "list":
|
||||
return self.sogo.addAddressbookContactList(addressbook_id, self.contact_name, self.contact_email)
|
||||
|
||||
def delete_contact(self):
|
||||
"""
|
||||
Delete a contact or contactlist from the addressbook.
|
||||
:return: Response from SOGo API.
|
||||
"""
|
||||
addressbook_id = self.sogo.getAddressbookIdByName(self.name)
|
||||
if not addressbook_id:
|
||||
print(f"Addressbook '{self.name}' not found for user '{self.username}'.")
|
||||
return None
|
||||
return self.sogo.deleteAddressbookItem(addressbook_id, self.contact_name)
|
||||
|
||||
def get(self):
|
||||
"""
|
||||
Retrieve addressbooks list.
|
||||
:return: Response from SOGo API.
|
||||
"""
|
||||
return self.sogo.getAddressbookList()
|
||||
|
||||
def delete(self):
|
||||
"""
|
||||
Delete the addressbook.
|
||||
:return: Response from SOGo API.
|
||||
"""
|
||||
|
||||
addressbook_id = self.sogo.getAddressbookIdByName(self.name)
|
||||
if not addressbook_id:
|
||||
print(f"Addressbook '{self.name}' not found for user '{self.username}'.")
|
||||
return None
|
||||
return self.sogo.deleteAddressbook(addressbook_id)
|
||||
|
||||
@classmethod
|
||||
def add_parser(cls, subparsers):
|
||||
parser = subparsers.add_parser(
|
||||
cls.parser_command,
|
||||
help="Manage addressbooks (add, delete, get, set_acl, get_acl, delete_acl, add_contact, delete_contact)"
|
||||
)
|
||||
parser.add_argument("object", choices=list(cls.required_args.keys()), help="Action to perform: add, delete, get, set_acl, get_acl, delete_acl, add_contact, delete_contact")
|
||||
parser.add_argument("--username", required=True, help="Username of the addressbook owner (e.g. user@example.com)")
|
||||
parser.add_argument("--name", help="Addressbook name")
|
||||
parser.add_argument("--sharee-email", help="Email address to share the addressbook with")
|
||||
parser.add_argument("--acl", help="ACL rights for the sharee (e.g. r, w, rw)")
|
||||
parser.add_argument("--subscribe", action='store_true', help="Subscribe the sharee to the addressbook")
|
||||
parser.add_argument("--contact-name", help="Name of the contact or contactlist to add or delete")
|
||||
parser.add_argument("--contact-email", help="Email address of the contact to add")
|
||||
parser.add_argument("--type", choices=["card", "list"], help="Type of contact to add: card (single contact) or list (distribution list)")
|
||||
|
||||
107
data/Dockerfiles/controller/mailcow-adm/models/AliasModel.py
Normal file
107
data/Dockerfiles/controller/mailcow-adm/models/AliasModel.py
Normal file
@@ -0,0 +1,107 @@
|
||||
from modules.Mailcow import Mailcow
|
||||
from models.BaseModel import BaseModel
|
||||
|
||||
class AliasModel(BaseModel):
|
||||
parser_command = "alias"
|
||||
required_args = {
|
||||
"add": [["address", "goto"]],
|
||||
"delete": [["id"]],
|
||||
"get": [["id"]],
|
||||
"edit": [["id"]]
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
id=None,
|
||||
address=None,
|
||||
goto=None,
|
||||
active=None,
|
||||
sogo_visible=None,
|
||||
**kwargs
|
||||
):
|
||||
self.mailcow = Mailcow()
|
||||
|
||||
self.id = id
|
||||
self.address = address
|
||||
self.goto = goto
|
||||
self.active = active
|
||||
self.sogo_visible = sogo_visible
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data):
|
||||
return cls(
|
||||
address=data.get("address"),
|
||||
goto=data.get("goto"),
|
||||
active=data.get("active", None),
|
||||
sogo_visible=data.get("sogo_visible", None)
|
||||
)
|
||||
|
||||
def getAdd(self):
|
||||
"""
|
||||
Get the alias details as a dictionary for adding, sets default values.
|
||||
:return: Dictionary containing alias details.
|
||||
"""
|
||||
|
||||
alias = {
|
||||
"address": self.address,
|
||||
"goto": self.goto,
|
||||
"active": self.active if self.active is not None else 1,
|
||||
"sogo_visible": self.sogo_visible if self.sogo_visible is not None else 0
|
||||
}
|
||||
return {key: value for key, value in alias.items() if value is not None}
|
||||
|
||||
def getEdit(self):
|
||||
"""
|
||||
Get the alias details as a dictionary for editing, sets no default values.
|
||||
:return: Dictionary containing mailbox details.
|
||||
"""
|
||||
|
||||
alias = {
|
||||
"address": self.address,
|
||||
"goto": self.goto,
|
||||
"active": self.active,
|
||||
"sogo_visible": self.sogo_visible
|
||||
}
|
||||
return {key: value for key, value in alias.items() if value is not None}
|
||||
|
||||
def get(self):
|
||||
"""
|
||||
Get the mailbox details from the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.getAlias(self.id)
|
||||
|
||||
def delete(self):
|
||||
"""
|
||||
Get the mailbox details from the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.deleteAlias(self.id)
|
||||
|
||||
def add(self):
|
||||
"""
|
||||
Get the mailbox details from the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.addAlias(self.getAdd())
|
||||
|
||||
def edit(self):
|
||||
"""
|
||||
Get the mailbox details from the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.editAlias(self.id, self.getEdit())
|
||||
|
||||
@classmethod
|
||||
def add_parser(cls, subparsers):
|
||||
parser = subparsers.add_parser(
|
||||
cls.parser_command,
|
||||
help="Manage aliases (add, delete, get, edit)"
|
||||
)
|
||||
parser.add_argument("object", choices=list(cls.required_args.keys()), help="Action to perform: add, delete, get, edit")
|
||||
parser.add_argument("--id", help="Alias object ID (required for get, edit, delete)")
|
||||
parser.add_argument("--address", help="Alias email address (e.g. alias@example.com)")
|
||||
parser.add_argument("--goto", help="Destination address(es), comma-separated (e.g. user1@example.com,user2@example.com)")
|
||||
parser.add_argument("--active", choices=["1", "0"], help="Activate (1) or deactivate (0) the alias")
|
||||
parser.add_argument("--sogo-visible", choices=["1", "0"], help="Show alias in SOGo addressbook (1 = yes, 0 = no)")
|
||||
|
||||
35
data/Dockerfiles/controller/mailcow-adm/models/BaseModel.py
Normal file
35
data/Dockerfiles/controller/mailcow-adm/models/BaseModel.py
Normal file
@@ -0,0 +1,35 @@
|
||||
class BaseModel:
|
||||
parser_command = ""
|
||||
required_args = {}
|
||||
|
||||
@classmethod
|
||||
def has_required_args(cls, args):
|
||||
"""
|
||||
Validate that all required arguments are present.
|
||||
"""
|
||||
object_name = args.object if hasattr(args, "object") else args.get("object")
|
||||
required_lists = cls.required_args.get(object_name, False)
|
||||
|
||||
if not required_lists:
|
||||
return False
|
||||
|
||||
for required_set in required_lists:
|
||||
result = True
|
||||
for required_args in required_set:
|
||||
if isinstance(args, dict):
|
||||
if not args.get(required_args):
|
||||
result = False
|
||||
break
|
||||
elif not hasattr(args, required_args):
|
||||
result = False
|
||||
break
|
||||
if result:
|
||||
break
|
||||
|
||||
if not result:
|
||||
print(f"Required arguments for '{object_name}': {required_lists}")
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def add_parser(cls, subparsers):
|
||||
pass
|
||||
111
data/Dockerfiles/controller/mailcow-adm/models/CalendarModel.py
Normal file
111
data/Dockerfiles/controller/mailcow-adm/models/CalendarModel.py
Normal file
@@ -0,0 +1,111 @@
|
||||
from modules.Sogo import Sogo
|
||||
from models.BaseModel import BaseModel
|
||||
|
||||
class CalendarModel(BaseModel):
|
||||
parser_command = "calendar"
|
||||
required_args = {
|
||||
"add": [["username", "name"]],
|
||||
"delete": [["username", "name"]],
|
||||
"get": [["username"]],
|
||||
"import_ics": [["username", "name", "ics"]],
|
||||
"set_acl": [["username", "name", "sharee_email", "acl"]],
|
||||
"get_acl": [["username", "name"]],
|
||||
"delete_acl": [["username", "name", "sharee_email"]],
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
username=None,
|
||||
name=None,
|
||||
sharee_email=None,
|
||||
acl=None,
|
||||
subscribe=None,
|
||||
ics=None,
|
||||
**kwargs
|
||||
):
|
||||
self.sogo = Sogo(username)
|
||||
|
||||
self.name = name
|
||||
self.acl = acl
|
||||
self.sharee_email = sharee_email
|
||||
self.subscribe = subscribe
|
||||
self.ics = ics
|
||||
|
||||
def add(self):
|
||||
"""
|
||||
Add a new calendar.
|
||||
:return: Response from SOGo API.
|
||||
"""
|
||||
return self.sogo.addCalendar(self.name)
|
||||
|
||||
def delete(self):
|
||||
"""
|
||||
Delete a calendar.
|
||||
:return: Response from SOGo API.
|
||||
"""
|
||||
calendar_id = self.sogo.getCalendarIdByName(self.name)
|
||||
if not calendar_id:
|
||||
print(f"Calendar '{self.name}' not found for user '{self.username}'.")
|
||||
return None
|
||||
return self.sogo.deleteCalendar(calendar_id)
|
||||
|
||||
def get(self):
|
||||
"""
|
||||
Get the calendar details.
|
||||
:return: Response from SOGo API.
|
||||
"""
|
||||
return self.sogo.getCalendar()
|
||||
|
||||
def set_acl(self):
|
||||
"""
|
||||
Set ACL for the calendar.
|
||||
:return: Response from SOGo API.
|
||||
"""
|
||||
calendar_id = self.sogo.getCalendarIdByName(self.name)
|
||||
if not calendar_id:
|
||||
print(f"Calendar '{self.name}' not found for user '{self.username}'.")
|
||||
return None
|
||||
return self.sogo.setCalendarACL(calendar_id, self.sharee_email, self.acl, self.subscribe)
|
||||
|
||||
def delete_acl(self):
|
||||
"""
|
||||
Delete the calendar ACL.
|
||||
:return: Response from SOGo API.
|
||||
"""
|
||||
calendar_id = self.sogo.getCalendarIdByName(self.name)
|
||||
if not calendar_id:
|
||||
print(f"Calendar '{self.name}' not found for user '{self.username}'.")
|
||||
return None
|
||||
return self.sogo.deleteCalendarACL(calendar_id, self.sharee_email)
|
||||
|
||||
def get_acl(self):
|
||||
"""
|
||||
Get the ACL for the calendar.
|
||||
:return: Response from SOGo API.
|
||||
"""
|
||||
calendar_id = self.sogo.getCalendarIdByName(self.name)
|
||||
if not calendar_id:
|
||||
print(f"Calendar '{self.name}' not found for user '{self.username}'.")
|
||||
return None
|
||||
return self.sogo.getCalendarACL(calendar_id)
|
||||
|
||||
def import_ics(self):
|
||||
"""
|
||||
Import a calendar from an ICS file.
|
||||
:return: Response from SOGo API.
|
||||
"""
|
||||
return self.sogo.importCalendar(self.name, self.ics)
|
||||
|
||||
@classmethod
|
||||
def add_parser(cls, subparsers):
|
||||
parser = subparsers.add_parser(
|
||||
cls.parser_command,
|
||||
help="Manage calendars (add, delete, get, import_ics, set_acl, get_acl, delete_acl)"
|
||||
)
|
||||
parser.add_argument("object", choices=list(cls.required_args.keys()), help="Action to perform: add, delete, get, import_ics, set_acl, get_acl, delete_acl")
|
||||
parser.add_argument("--username", required=True, help="Username of the calendar owner (e.g. user@example.com)")
|
||||
parser.add_argument("--name", help="Calendar name")
|
||||
parser.add_argument("--ics", help="Path to ICS file for import")
|
||||
parser.add_argument("--sharee-email", help="Email address to share the calendar with")
|
||||
parser.add_argument("--acl", help="ACL rights for the sharee (e.g. r, w, rw)")
|
||||
parser.add_argument("--subscribe", action='store_true', help="Subscribe the sharee to the calendar")
|
||||
162
data/Dockerfiles/controller/mailcow-adm/models/DomainModel.py
Normal file
162
data/Dockerfiles/controller/mailcow-adm/models/DomainModel.py
Normal file
@@ -0,0 +1,162 @@
|
||||
from modules.Mailcow import Mailcow
|
||||
from models.BaseModel import BaseModel
|
||||
|
||||
class DomainModel(BaseModel):
|
||||
parser_command = "domain"
|
||||
required_args = {
|
||||
"add": [["domain"]],
|
||||
"delete": [["domain"]],
|
||||
"get": [["domain"]],
|
||||
"edit": [["domain"]]
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
domain=None,
|
||||
active=None,
|
||||
aliases=None,
|
||||
backupmx=None,
|
||||
defquota=None,
|
||||
description=None,
|
||||
mailboxes=None,
|
||||
maxquota=None,
|
||||
quota=None,
|
||||
relay_all_recipients=None,
|
||||
rl_frame=None,
|
||||
rl_value=None,
|
||||
restart_sogo=None,
|
||||
tags=None,
|
||||
**kwargs
|
||||
):
|
||||
self.mailcow = Mailcow()
|
||||
|
||||
self.domain = domain
|
||||
self.active = active
|
||||
self.aliases = aliases
|
||||
self.backupmx = backupmx
|
||||
self.defquota = defquota
|
||||
self.description = description
|
||||
self.mailboxes = mailboxes
|
||||
self.maxquota = maxquota
|
||||
self.quota = quota
|
||||
self.relay_all_recipients = relay_all_recipients
|
||||
self.rl_frame = rl_frame
|
||||
self.rl_value = rl_value
|
||||
self.restart_sogo = restart_sogo
|
||||
self.tags = tags
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data):
|
||||
return cls(
|
||||
domain=data.get("domain"),
|
||||
active=data.get("active", None),
|
||||
aliases=data.get("aliases", None),
|
||||
backupmx=data.get("backupmx", None),
|
||||
defquota=data.get("defquota", None),
|
||||
description=data.get("description", None),
|
||||
mailboxes=data.get("mailboxes", None),
|
||||
maxquota=data.get("maxquota", None),
|
||||
quota=data.get("quota", None),
|
||||
relay_all_recipients=data.get("relay_all_recipients", None),
|
||||
rl_frame=data.get("rl_frame", None),
|
||||
rl_value=data.get("rl_value", None),
|
||||
restart_sogo=data.get("restart_sogo", None),
|
||||
tags=data.get("tags", None)
|
||||
)
|
||||
|
||||
def getAdd(self):
|
||||
"""
|
||||
Get the domain details as a dictionary for adding, sets default values.
|
||||
:return: Dictionary containing domain details.
|
||||
"""
|
||||
domain = {
|
||||
"domain": self.domain,
|
||||
"active": self.active if self.active is not None else 1,
|
||||
"aliases": self.aliases if self.aliases is not None else 400,
|
||||
"backupmx": self.backupmx if self.backupmx is not None else 0,
|
||||
"defquota": self.defquota if self.defquota is not None else 3072,
|
||||
"description": self.description if self.description is not None else "",
|
||||
"mailboxes": self.mailboxes if self.mailboxes is not None else 10,
|
||||
"maxquota": self.maxquota if self.maxquota is not None else 10240,
|
||||
"quota": self.quota if self.quota is not None else 10240,
|
||||
"relay_all_recipients": self.relay_all_recipients if self.relay_all_recipients is not None else 0,
|
||||
"rl_frame": self.rl_frame,
|
||||
"rl_value": self.rl_value,
|
||||
"restart_sogo": self.restart_sogo if self.restart_sogo is not None else 0,
|
||||
"tags": self.tags if self.tags is not None else []
|
||||
}
|
||||
return {key: value for key, value in domain.items() if value is not None}
|
||||
|
||||
def getEdit(self):
|
||||
"""
|
||||
Get the domain details as a dictionary for editing, sets no default values.
|
||||
:return: Dictionary containing domain details.
|
||||
"""
|
||||
domain = {
|
||||
"domain": self.domain,
|
||||
"active": self.active,
|
||||
"aliases": self.aliases,
|
||||
"backupmx": self.backupmx,
|
||||
"defquota": self.defquota,
|
||||
"description": self.description,
|
||||
"mailboxes": self.mailboxes,
|
||||
"maxquota": self.maxquota,
|
||||
"quota": self.quota,
|
||||
"relay_all_recipients": self.relay_all_recipients,
|
||||
"rl_frame": self.rl_frame,
|
||||
"rl_value": self.rl_value,
|
||||
"restart_sogo": self.restart_sogo,
|
||||
"tags": self.tags
|
||||
}
|
||||
return {key: value for key, value in domain.items() if value is not None}
|
||||
|
||||
def get(self):
|
||||
"""
|
||||
Get the domain details from the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.getDomain(self.domain)
|
||||
|
||||
def delete(self):
|
||||
"""
|
||||
Delete the domain from the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.deleteDomain(self.domain)
|
||||
|
||||
def add(self):
|
||||
"""
|
||||
Add the domain to the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.addDomain(self.getAdd())
|
||||
|
||||
def edit(self):
|
||||
"""
|
||||
Edit the domain in the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.editDomain(self.domain, self.getEdit())
|
||||
|
||||
@classmethod
|
||||
def add_parser(cls, subparsers):
|
||||
parser = subparsers.add_parser(
|
||||
cls.parser_command,
|
||||
help="Manage domains (add, delete, get, edit)"
|
||||
)
|
||||
parser.add_argument("object", choices=list(cls.required_args.keys()), help="Action to perform: add, delete, get, edit")
|
||||
parser.add_argument("--domain", required=True, help="Domain name (e.g. domain.tld)")
|
||||
parser.add_argument("--active", choices=["1", "0"], help="Activate (1) or deactivate (0) the domain")
|
||||
parser.add_argument("--aliases", help="Number of aliases allowed for the domain")
|
||||
parser.add_argument("--backupmx", choices=["1", "0"], help="Enable (1) or disable (0) backup MX")
|
||||
parser.add_argument("--defquota", help="Default quota for mailboxes in MB")
|
||||
parser.add_argument("--description", help="Description of the domain")
|
||||
parser.add_argument("--mailboxes", help="Number of mailboxes allowed for the domain")
|
||||
parser.add_argument("--maxquota", help="Maximum quota for the domain in MB")
|
||||
parser.add_argument("--quota", help="Quota used by the domain in MB")
|
||||
parser.add_argument("--relay-all-recipients", choices=["1", "0"], help="Relay all recipients (1 = yes, 0 = no)")
|
||||
parser.add_argument("--rl-frame", help="Rate limit frame (e.g., s, m, h)")
|
||||
parser.add_argument("--rl-value", help="Rate limit value")
|
||||
parser.add_argument("--restart-sogo", help="Restart SOGo after changes (1 = yes, 0 = no)")
|
||||
parser.add_argument("--tags", nargs="*", help="Tags for the domain")
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
from modules.Mailcow import Mailcow
|
||||
from models.BaseModel import BaseModel
|
||||
|
||||
class DomainadminModel(BaseModel):
|
||||
parser_command = "domainadmin"
|
||||
required_args = {
|
||||
"add": [["username", "domains", "password"]],
|
||||
"delete": [["username"]],
|
||||
"get": [["username"]],
|
||||
"edit": [["username"]]
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
username=None,
|
||||
domains=None,
|
||||
password=None,
|
||||
active=None,
|
||||
**kwargs
|
||||
):
|
||||
self.mailcow = Mailcow()
|
||||
|
||||
self.username = username
|
||||
self.domains = domains
|
||||
self.password = password
|
||||
self.password2 = password
|
||||
self.active = active
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data):
|
||||
return cls(
|
||||
username=data.get("username"),
|
||||
domains=data.get("domains"),
|
||||
password=data.get("password"),
|
||||
active=data.get("active", None),
|
||||
)
|
||||
|
||||
def getAdd(self):
|
||||
"""
|
||||
Get the domain admin details as a dictionary for adding, sets default values.
|
||||
:return: Dictionary containing domain admin details.
|
||||
"""
|
||||
domainadmin = {
|
||||
"username": self.username,
|
||||
"domains": self.domains,
|
||||
"password": self.password,
|
||||
"password2": self.password2,
|
||||
"active": self.active if self.active is not None else "1"
|
||||
}
|
||||
return {key: value for key, value in domainadmin.items() if value is not None}
|
||||
|
||||
def getEdit(self):
|
||||
"""
|
||||
Get the domain admin details as a dictionary for editing, sets no default values.
|
||||
:return: Dictionary containing domain admin details.
|
||||
"""
|
||||
domainadmin = {
|
||||
"username": self.username,
|
||||
"domains": self.domains,
|
||||
"password": self.password,
|
||||
"password2": self.password2,
|
||||
"active": self.active
|
||||
}
|
||||
return {key: value for key, value in domainadmin.items() if value is not None}
|
||||
|
||||
def get(self):
|
||||
"""
|
||||
Get the domain admin details from the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.getDomainadmin(self.username)
|
||||
|
||||
def delete(self):
|
||||
"""
|
||||
Delete the domain admin from the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.deleteDomainadmin(self.username)
|
||||
|
||||
def add(self):
|
||||
"""
|
||||
Add the domain admin to the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.addDomainadmin(self.getAdd())
|
||||
|
||||
def edit(self):
|
||||
"""
|
||||
Edit the domain admin in the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.editDomainadmin(self.username, self.getEdit())
|
||||
|
||||
@classmethod
|
||||
def add_parser(cls, subparsers):
|
||||
parser = subparsers.add_parser(
|
||||
cls.parser_command,
|
||||
help="Manage domain admins (add, delete, get, edit)"
|
||||
)
|
||||
parser.add_argument("object", choices=list(cls.required_args.keys()), help="Action to perform: add, delete, get, edit")
|
||||
parser.add_argument("--username", help="Username for the domain admin")
|
||||
parser.add_argument("--domains", help="Comma-separated list of domains")
|
||||
parser.add_argument("--password", help="Password for the domain admin")
|
||||
parser.add_argument("--active", choices=["1", "0"], help="Activate (1) or deactivate (0) the domain admin")
|
||||
|
||||
163
data/Dockerfiles/controller/mailcow-adm/models/MailboxModel.py
Normal file
163
data/Dockerfiles/controller/mailcow-adm/models/MailboxModel.py
Normal file
@@ -0,0 +1,163 @@
|
||||
from modules.Mailcow import Mailcow
|
||||
from models.BaseModel import BaseModel
|
||||
|
||||
class MailboxModel(BaseModel):
|
||||
parser_command = "mailbox"
|
||||
required_args = {
|
||||
"add": [["username", "password"]],
|
||||
"delete": [["username"]],
|
||||
"get": [["username"]],
|
||||
"edit": [["username"]]
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
password=None,
|
||||
username=None,
|
||||
domain=None,
|
||||
local_part=None,
|
||||
active=None,
|
||||
sogo_access=None,
|
||||
name=None,
|
||||
authsource=None,
|
||||
quota=None,
|
||||
force_pw_update=None,
|
||||
tls_enforce_in=None,
|
||||
tls_enforce_out=None,
|
||||
tags=None,
|
||||
sender_acl=None,
|
||||
**kwargs
|
||||
):
|
||||
self.mailcow = Mailcow()
|
||||
|
||||
if username is not None and "@" in username:
|
||||
self.username = username
|
||||
self.local_part, self.domain = username.split("@")
|
||||
else:
|
||||
self.username = f"{local_part}@{domain}"
|
||||
self.local_part = local_part
|
||||
self.domain = domain
|
||||
|
||||
self.password = password
|
||||
self.password2 = password
|
||||
self.active = active
|
||||
self.sogo_access = sogo_access
|
||||
self.name = name
|
||||
self.authsource = authsource
|
||||
self.quota = quota
|
||||
self.force_pw_update = force_pw_update
|
||||
self.tls_enforce_in = tls_enforce_in
|
||||
self.tls_enforce_out = tls_enforce_out
|
||||
self.tags = tags
|
||||
self.sender_acl = sender_acl
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data):
|
||||
return cls(
|
||||
domain=data.get("domain"),
|
||||
local_part=data.get("local_part"),
|
||||
password=data.get("password"),
|
||||
active=data.get("active", None),
|
||||
sogo_access=data.get("sogo_access", None),
|
||||
name=data.get("name", None),
|
||||
authsource=data.get("authsource", None),
|
||||
quota=data.get("quota", None),
|
||||
force_pw_update=data.get("force_pw_update", None),
|
||||
tls_enforce_in=data.get("tls_enforce_in", None),
|
||||
tls_enforce_out=data.get("tls_enforce_out", None),
|
||||
tags=data.get("tags", None),
|
||||
sender_acl=data.get("sender_acl", None)
|
||||
)
|
||||
|
||||
def getAdd(self):
|
||||
"""
|
||||
Get the mailbox details as a dictionary for adding, sets default values.
|
||||
:return: Dictionary containing mailbox details.
|
||||
"""
|
||||
|
||||
mailbox = {
|
||||
"domain": self.domain,
|
||||
"local_part": self.local_part,
|
||||
"password": self.password,
|
||||
"password2": self.password2,
|
||||
"active": self.active if self.active is not None else 1,
|
||||
"name": self.name if self.name is not None else "",
|
||||
"authsource": self.authsource if self.authsource is not None else "mailcow",
|
||||
"quota": self.quota if self.quota is not None else 0,
|
||||
"force_pw_update": self.force_pw_update if self.force_pw_update is not None else 0,
|
||||
"tls_enforce_in": self.tls_enforce_in if self.tls_enforce_in is not None else 0,
|
||||
"tls_enforce_out": self.tls_enforce_out if self.tls_enforce_out is not None else 0,
|
||||
"tags": self.tags if self.tags is not None else []
|
||||
}
|
||||
return {key: value for key, value in mailbox.items() if value is not None}
|
||||
|
||||
def getEdit(self):
|
||||
"""
|
||||
Get the mailbox details as a dictionary for editing, sets no default values.
|
||||
:return: Dictionary containing mailbox details.
|
||||
"""
|
||||
|
||||
mailbox = {
|
||||
"domain": self.domain,
|
||||
"local_part": self.local_part,
|
||||
"password": self.password,
|
||||
"password2": self.password2,
|
||||
"active": self.active,
|
||||
"name": self.name,
|
||||
"authsource": self.authsource,
|
||||
"quota": self.quota,
|
||||
"force_pw_update": self.force_pw_update,
|
||||
"tls_enforce_in": self.tls_enforce_in,
|
||||
"tls_enforce_out": self.tls_enforce_out,
|
||||
"tags": self.tags
|
||||
}
|
||||
return {key: value for key, value in mailbox.items() if value is not None}
|
||||
|
||||
def get(self):
|
||||
"""
|
||||
Get the mailbox details from the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.getMailbox(self.username)
|
||||
|
||||
def delete(self):
|
||||
"""
|
||||
Get the mailbox details from the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.deleteMailbox(self.username)
|
||||
|
||||
def add(self):
|
||||
"""
|
||||
Get the mailbox details from the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.addMailbox(self.getAdd())
|
||||
|
||||
def edit(self):
|
||||
"""
|
||||
Get the mailbox details from the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.editMailbox(self.username, self.getEdit())
|
||||
|
||||
@classmethod
|
||||
def add_parser(cls, subparsers):
|
||||
parser = subparsers.add_parser(
|
||||
cls.parser_command,
|
||||
help="Manage mailboxes (add, delete, get, edit)"
|
||||
)
|
||||
parser.add_argument("object", choices=list(cls.required_args.keys()), help="Action to perform: add, delete, get, edit")
|
||||
parser.add_argument("--username", help="Full email address of the mailbox (e.g. user@example.com)")
|
||||
parser.add_argument("--password", help="Password for the mailbox (required for add)")
|
||||
parser.add_argument("--active", choices=["1", "0"], help="Activate (1) or deactivate (0) the mailbox")
|
||||
parser.add_argument("--sogo-access", choices=["1", "0"], help="Redirect mailbox to SOGo after web login (1 = yes, 0 = no)")
|
||||
parser.add_argument("--name", help="Display name of the mailbox owner")
|
||||
parser.add_argument("--authsource", help="Authentication source (default: mailcow)")
|
||||
parser.add_argument("--quota", help="Mailbox quota in bytes (0 = unlimited)")
|
||||
parser.add_argument("--force-pw-update", choices=["1", "0"], help="Force password update on next login (1 = yes, 0 = no)")
|
||||
parser.add_argument("--tls-enforce-in", choices=["1", "0"], help="Enforce TLS for incoming emails (1 = yes, 0 = no)")
|
||||
parser.add_argument("--tls-enforce-out", choices=["1", "0"], help="Enforce TLS for outgoing emails (1 = yes, 0 = no)")
|
||||
parser.add_argument("--tags", help="Comma-separated list of tags for the mailbox")
|
||||
parser.add_argument("--sender-acl", help="Comma-separated list of allowed sender addresses for this mailbox")
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
from modules.Dovecot import Dovecot
|
||||
from models.BaseModel import BaseModel
|
||||
|
||||
class MaildirModel(BaseModel):
|
||||
parser_command = "maildir"
|
||||
required_args = {
|
||||
"encrypt": [],
|
||||
"decrypt": [],
|
||||
"restore": [["username", "item"], ["list"]]
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
username=None,
|
||||
source=None,
|
||||
item=None,
|
||||
overwrite=None,
|
||||
list=None,
|
||||
**kwargs
|
||||
):
|
||||
self.dovecot = Dovecot()
|
||||
|
||||
for key, value in kwargs.items():
|
||||
setattr(self, key, value)
|
||||
|
||||
self.username = username
|
||||
self.source = source
|
||||
self.item = item
|
||||
self.overwrite = overwrite
|
||||
self.list = list
|
||||
|
||||
def encrypt(self):
|
||||
"""
|
||||
Encrypt the maildir for the specified user or all.
|
||||
:return: Response from Dovecot.
|
||||
"""
|
||||
return self.dovecot.encryptMaildir(self.source_dir, self.output_dir)
|
||||
|
||||
def decrypt(self):
|
||||
"""
|
||||
Decrypt the maildir for the specified user or all.
|
||||
:return: Response from Dovecot.
|
||||
"""
|
||||
return self.dovecot.decryptMaildir(self.source_dir, self.output_dir)
|
||||
|
||||
def restore(self):
|
||||
"""
|
||||
Restore or List maildir data for the specified user.
|
||||
:return: Response from Dovecot.
|
||||
"""
|
||||
if self.list:
|
||||
return self.dovecot.listDeletedMaildirs()
|
||||
return self.dovecot.restoreMaildir(self.username, self.item)
|
||||
|
||||
|
||||
@classmethod
|
||||
def add_parser(cls, subparsers):
|
||||
parser = subparsers.add_parser(
|
||||
cls.parser_command,
|
||||
help="Manage maildir (encrypt, decrypt, restore)"
|
||||
)
|
||||
parser.add_argument("object", choices=list(cls.required_args.keys()), help="Action to perform: encrypt, decrypt, restore")
|
||||
parser.add_argument("--item", help="Item to restore")
|
||||
parser.add_argument("--username", help="Username to restore the item to")
|
||||
parser.add_argument("--list", action="store_true", help="List items to restore")
|
||||
parser.add_argument("--source-dir", help="Path to the source maildir to import/encrypt/decrypt")
|
||||
parser.add_argument("--output-dir", help="Directory to store encrypted/decrypted files inside the Dovecot container")
|
||||
@@ -0,0 +1,62 @@
|
||||
import json
|
||||
from models.BaseModel import BaseModel
|
||||
from modules.Mailer import Mailer
|
||||
|
||||
class MailerModel(BaseModel):
|
||||
parser_command = "mail"
|
||||
required_args = {
|
||||
"send": [["sender", "recipient", "subject", "body"]]
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
sender=None,
|
||||
recipient=None,
|
||||
subject=None,
|
||||
body=None,
|
||||
context=None,
|
||||
**kwargs
|
||||
):
|
||||
self.sender = sender
|
||||
self.recipient = recipient
|
||||
self.subject = subject
|
||||
self.body = body
|
||||
self.context = context
|
||||
|
||||
def send(self):
|
||||
if self.context is not None:
|
||||
try:
|
||||
self.context = json.loads(self.context)
|
||||
except json.JSONDecodeError as e:
|
||||
return f"Invalid context JSON: {e}"
|
||||
else:
|
||||
self.context = {}
|
||||
|
||||
mailer = Mailer(
|
||||
smtp_host="postfix-mailcow",
|
||||
smtp_port=25,
|
||||
username=self.sender,
|
||||
password="",
|
||||
use_tls=True
|
||||
)
|
||||
res = mailer.send_mail(
|
||||
subject=self.subject,
|
||||
from_addr=self.sender,
|
||||
to_addrs=self.recipient.split(","),
|
||||
template=self.body,
|
||||
context=self.context
|
||||
)
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def add_parser(cls, subparsers):
|
||||
parser = subparsers.add_parser(
|
||||
cls.parser_command,
|
||||
help="Send emails via SMTP"
|
||||
)
|
||||
parser.add_argument("object", choices=list(cls.required_args.keys()), help="Action to perform: send")
|
||||
parser.add_argument("--sender", required=True, help="Email sender address")
|
||||
parser.add_argument("--recipient", required=True, help="Email recipient address (comma-separated for multiple)")
|
||||
parser.add_argument("--subject", required=True, help="Email subject")
|
||||
parser.add_argument("--body", required=True, help="Email body (Jinja2 template supported)")
|
||||
parser.add_argument("--context", help="Context for Jinja2 template rendering (JSON format)")
|
||||
@@ -0,0 +1,45 @@
|
||||
from modules.Mailcow import Mailcow
|
||||
from models.BaseModel import BaseModel
|
||||
|
||||
class StatusModel(BaseModel):
|
||||
parser_command = "status"
|
||||
required_args = {
|
||||
"version": [[]],
|
||||
"vmail": [[]],
|
||||
"containers": [[]]
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
**kwargs
|
||||
):
|
||||
self.mailcow = Mailcow()
|
||||
|
||||
def version(self):
|
||||
"""
|
||||
Get the version of the mailcow instance.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.getStatusVersion()
|
||||
|
||||
def vmail(self):
|
||||
"""
|
||||
Get the vmail details from the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.getStatusVmail()
|
||||
|
||||
def containers(self):
|
||||
"""
|
||||
Get the status of containers in the mailcow instance.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.getStatusContainers()
|
||||
|
||||
@classmethod
|
||||
def add_parser(cls, subparsers):
|
||||
parser = subparsers.add_parser(
|
||||
cls.parser_command,
|
||||
help="Get information about mailcow (version, vmail, containers)"
|
||||
)
|
||||
parser.add_argument("object", choices=list(cls.required_args.keys()), help="Action to perform: version, vmail, containers")
|
||||
221
data/Dockerfiles/controller/mailcow-adm/models/SyncjobModel.py
Normal file
221
data/Dockerfiles/controller/mailcow-adm/models/SyncjobModel.py
Normal file
@@ -0,0 +1,221 @@
|
||||
from modules.Mailcow import Mailcow
|
||||
from models.BaseModel import BaseModel
|
||||
|
||||
class SyncjobModel(BaseModel):
|
||||
parser_command = "syncjob"
|
||||
required_args = {
|
||||
"add": [["username", "host1", "port1", "user1", "password1", "enc1"]],
|
||||
"delete": [["id"]],
|
||||
"get": [["username"]],
|
||||
"edit": [["id"]],
|
||||
"run": [["id"]]
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
id=None,
|
||||
username=None,
|
||||
host1=None,
|
||||
port1=None,
|
||||
user1=None,
|
||||
password1=None,
|
||||
enc1=None,
|
||||
mins_interval=None,
|
||||
subfolder2=None,
|
||||
maxage=None,
|
||||
maxbytespersecond=None,
|
||||
timeout1=None,
|
||||
timeout2=None,
|
||||
exclude=None,
|
||||
custom_parameters=None,
|
||||
delete2duplicates=None,
|
||||
delete1=None,
|
||||
delete2=None,
|
||||
automap=None,
|
||||
skipcrossduplicates=None,
|
||||
subscribeall=None,
|
||||
active=None,
|
||||
force=None,
|
||||
**kwargs
|
||||
):
|
||||
self.mailcow = Mailcow()
|
||||
|
||||
for key, value in kwargs.items():
|
||||
setattr(self, key, value)
|
||||
|
||||
self.id = id
|
||||
self.username = username
|
||||
self.host1 = host1
|
||||
self.port1 = port1
|
||||
self.user1 = user1
|
||||
self.password1 = password1
|
||||
self.enc1 = enc1
|
||||
self.mins_interval = mins_interval
|
||||
self.subfolder2 = subfolder2
|
||||
self.maxage = maxage
|
||||
self.maxbytespersecond = maxbytespersecond
|
||||
self.timeout1 = timeout1
|
||||
self.timeout2 = timeout2
|
||||
self.exclude = exclude
|
||||
self.custom_parameters = custom_parameters
|
||||
self.delete2duplicates = delete2duplicates
|
||||
self.delete1 = delete1
|
||||
self.delete2 = delete2
|
||||
self.automap = automap
|
||||
self.skipcrossduplicates = skipcrossduplicates
|
||||
self.subscribeall = subscribeall
|
||||
self.active = active
|
||||
self.force = force
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data):
|
||||
return cls(
|
||||
username=data.get("username"),
|
||||
host1=data.get("host1"),
|
||||
port1=data.get("port1"),
|
||||
user1=data.get("user1"),
|
||||
password1=data.get("password1"),
|
||||
enc1=data.get("enc1"),
|
||||
mins_interval=data.get("mins_interval", None),
|
||||
subfolder2=data.get("subfolder2", None),
|
||||
maxage=data.get("maxage", None),
|
||||
maxbytespersecond=data.get("maxbytespersecond", None),
|
||||
timeout1=data.get("timeout1", None),
|
||||
timeout2=data.get("timeout2", None),
|
||||
exclude=data.get("exclude", None),
|
||||
custom_parameters=data.get("custom_parameters", None),
|
||||
delete2duplicates=data.get("delete2duplicates", None),
|
||||
delete1=data.get("delete1", None),
|
||||
delete2=data.get("delete2", None),
|
||||
automap=data.get("automap", None),
|
||||
skipcrossduplicates=data.get("skipcrossduplicates", None),
|
||||
subscribeall=data.get("subscribeall", None),
|
||||
active=data.get("active", None),
|
||||
)
|
||||
|
||||
def getAdd(self):
|
||||
"""
|
||||
Get the sync job details as a dictionary for adding, sets default values.
|
||||
:return: Dictionary containing sync job details.
|
||||
"""
|
||||
syncjob = {
|
||||
"username": self.username,
|
||||
"host1": self.host1,
|
||||
"port1": self.port1,
|
||||
"user1": self.user1,
|
||||
"password1": self.password1,
|
||||
"enc1": self.enc1,
|
||||
"mins_interval": self.mins_interval if self.mins_interval is not None else 20,
|
||||
"subfolder2": self.subfolder2 if self.subfolder2 is not None else "",
|
||||
"maxage": self.maxage if self.maxage is not None else 0,
|
||||
"maxbytespersecond": self.maxbytespersecond if self.maxbytespersecond is not None else 0,
|
||||
"timeout1": self.timeout1 if self.timeout1 is not None else 600,
|
||||
"timeout2": self.timeout2 if self.timeout2 is not None else 600,
|
||||
"exclude": self.exclude if self.exclude is not None else "(?i)spam|(?i)junk",
|
||||
"custom_parameters": self.custom_parameters if self.custom_parameters is not None else "",
|
||||
"delete2duplicates": 1 if self.delete2duplicates else 0,
|
||||
"delete1": 1 if self.delete1 else 0,
|
||||
"delete2": 1 if self.delete2 else 0,
|
||||
"automap": 1 if self.automap else 0,
|
||||
"skipcrossduplicates": 1 if self.skipcrossduplicates else 0,
|
||||
"subscribeall": 1 if self.subscribeall else 0,
|
||||
"active": 1 if self.active else 0
|
||||
}
|
||||
return {key: value for key, value in syncjob.items() if value is not None}
|
||||
|
||||
def getEdit(self):
|
||||
"""
|
||||
Get the sync job details as a dictionary for editing, sets no default values.
|
||||
:return: Dictionary containing sync job details.
|
||||
"""
|
||||
syncjob = {
|
||||
"username": self.username,
|
||||
"host1": self.host1,
|
||||
"port1": self.port1,
|
||||
"user1": self.user1,
|
||||
"password1": self.password1,
|
||||
"enc1": self.enc1,
|
||||
"mins_interval": self.mins_interval,
|
||||
"subfolder2": self.subfolder2,
|
||||
"maxage": self.maxage,
|
||||
"maxbytespersecond": self.maxbytespersecond,
|
||||
"timeout1": self.timeout1,
|
||||
"timeout2": self.timeout2,
|
||||
"exclude": self.exclude,
|
||||
"custom_parameters": self.custom_parameters,
|
||||
"delete2duplicates": self.delete2duplicates,
|
||||
"delete1": self.delete1,
|
||||
"delete2": self.delete2,
|
||||
"automap": self.automap,
|
||||
"skipcrossduplicates": self.skipcrossduplicates,
|
||||
"subscribeall": self.subscribeall,
|
||||
"active": self.active
|
||||
}
|
||||
return {key: value for key, value in syncjob.items() if value is not None}
|
||||
|
||||
def get(self):
|
||||
"""
|
||||
Get the mailbox details from the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.getSyncjob(self.username)
|
||||
|
||||
def delete(self):
|
||||
"""
|
||||
Get the mailbox details from the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.deleteSyncjob(self.id)
|
||||
|
||||
def add(self):
|
||||
"""
|
||||
Get the mailbox details from the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.addSyncjob(self.getAdd())
|
||||
|
||||
def edit(self):
|
||||
"""
|
||||
Get the mailbox details from the mailcow API.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.editSyncjob(self.id, self.getEdit())
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
Run the sync job.
|
||||
:return: Response from the mailcow API.
|
||||
"""
|
||||
return self.mailcow.runSyncjob(self.id, force=self.force)
|
||||
|
||||
@classmethod
|
||||
def add_parser(cls, subparsers):
|
||||
parser = subparsers.add_parser(
|
||||
cls.parser_command,
|
||||
help="Manage sync jobs (add, delete, get, edit)"
|
||||
)
|
||||
parser.add_argument("object", choices=list(cls.required_args.keys()), help="Action to perform: add, delete, get, edit")
|
||||
parser.add_argument("--id", help="Syncjob object ID (required for edit, delete, run)")
|
||||
parser.add_argument("--username", help="Target mailbox username (e.g. user@example.com)")
|
||||
parser.add_argument("--host1", help="Source IMAP server hostname")
|
||||
parser.add_argument("--port1", help="Source IMAP server port")
|
||||
parser.add_argument("--user1", help="Source IMAP account username")
|
||||
parser.add_argument("--password1", help="Source IMAP account password")
|
||||
parser.add_argument("--enc1", choices=["PLAIN", "SSL", "TLS"], help="Encryption for source server connection")
|
||||
parser.add_argument("--mins-interval", help="Sync interval in minutes (default: 20)")
|
||||
parser.add_argument("--subfolder2", help="Destination subfolder (default: empty)")
|
||||
parser.add_argument("--maxage", help="Maximum mail age in days (default: 0 = unlimited)")
|
||||
parser.add_argument("--maxbytespersecond", help="Maximum bandwidth in bytes/sec (default: 0 = unlimited)")
|
||||
parser.add_argument("--timeout1", help="Timeout for source server in seconds (default: 600)")
|
||||
parser.add_argument("--timeout2", help="Timeout for destination server in seconds (default: 600)")
|
||||
parser.add_argument("--exclude", help="Regex pattern to exclude folders (default: (?i)spam|(?i)junk)")
|
||||
parser.add_argument("--custom-parameters", help="Additional imapsync parameters")
|
||||
parser.add_argument("--delete2duplicates", choices=["1", "0"], help="Delete duplicates on destination (1 = yes, 0 = no)")
|
||||
parser.add_argument("--del1", choices=["1", "0"], help="Delete mails on source after sync (1 = yes, 0 = no)")
|
||||
parser.add_argument("--del2", choices=["1", "0"], help="Delete mails on destination after sync (1 = yes, 0 = no)")
|
||||
parser.add_argument("--automap", choices=["1", "0"], help="Enable folder automapping (1 = yes, 0 = no)")
|
||||
parser.add_argument("--skipcrossduplicates", choices=["1", "0"], help="Skip cross-account duplicates (1 = yes, 0 = no)")
|
||||
parser.add_argument("--subscribeall", choices=["1", "0"], help="Subscribe to all folders (1 = yes, 0 = no)")
|
||||
parser.add_argument("--active", choices=["1", "0"], help="Activate syncjob (1 = yes, 0 = no)")
|
||||
parser.add_argument("--force", action="store_true", help="Force the syncjob to run even if it is not active")
|
||||
|
||||
Reference in New Issue
Block a user