Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
e8d45fc477 | |||
8000779fe8 | |||
8814127cf8 | |||
f653a20d35 | |||
7f12bd3743 | |||
8a6eceb9a5 | |||
2bd8ddeb04 | |||
f3ba4f7d67 | |||
37d670b54e | |||
12215074d6 | |||
15e8f8ac90 |
@@ -4,7 +4,7 @@ _malias_ is a helper for mailcow instances. You can create, delete, search and l
|
||||
|
||||
## Installation
|
||||
|
||||
Download the latest relase from https://gitlab.pm/rune/malias/releases. Unzip and move to a folder in you path (ease of use). You can also rename the file ```malias.py``` to just ```malias``` and make the file executable with ```chmod +x malias```. To install required python modules run ```pip3 install -r requirements.txt```
|
||||
Download the latest release from https://gitlab.pm/rune/malias/releases. Unzip and move to a folder in you path (ease of use). I also recommend rename the file ```malias.py``` to just ```malias``` and make the file executable with ```chmod +x malias```. To install required python modules run ```pip3 install -r requirements.txt```
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -14,6 +14,10 @@ For instructions run
|
||||
malias -h
|
||||
```
|
||||
|
||||
## Screenshot
|
||||
|
||||

|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests are welcome. For major changes, please open an issue first
|
||||
|
BIN
malias.png
Normal file
BIN
malias.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 573 KiB |
183
malias.py
Normal file → Executable file
183
malias.py
Normal file → Executable file
@@ -10,12 +10,12 @@ import requests
|
||||
import os
|
||||
import time
|
||||
import sys
|
||||
import git
|
||||
from types import SimpleNamespace
|
||||
from datetime import datetime
|
||||
from string import ascii_letters, digits
|
||||
from rich import print
|
||||
from argparse import RawTextHelpFormatter
|
||||
#from urllib import Request, urlopen
|
||||
from urllib.request import urlopen
|
||||
|
||||
# Info pages for dev
|
||||
@@ -29,9 +29,26 @@ database = filepath.joinpath('malias.db')
|
||||
logfile = filepath.joinpath('malias.log')
|
||||
Path(filepath).mkdir(parents=True, exist_ok=True)
|
||||
logging.basicConfig(filename=logfile,level=logging.INFO,format='%(message)s')
|
||||
app_version = '0.2.1'
|
||||
app_version = '0.3.1'
|
||||
|
||||
|
||||
def get_latest_release():
|
||||
req = urllib.request.Request('https://gitlab.pm/api/v1/repos/rune/malias/releases/latest')
|
||||
req.add_header('Content-Type', 'application/json')
|
||||
current = urllib.request.urlopen(req)
|
||||
remote = current.read().decode('utf-8')
|
||||
remoteData = json.loads(remote)
|
||||
return remoteData['tag_name']
|
||||
|
||||
|
||||
def release_check():
|
||||
latest_release = get_latest_release()
|
||||
if app_version != latest_release:
|
||||
print('[b]New version available @ [i]https://iurl.no/malias[/b][/i]')
|
||||
else:
|
||||
print ('You have the the latest version. Version: %s' %(app_version))
|
||||
|
||||
|
||||
def connect_database():
|
||||
Path(filepath).mkdir(parents=True, exist_ok=True)
|
||||
conn = None
|
||||
@@ -99,6 +116,7 @@ def get_settings(kind):
|
||||
|
||||
|
||||
def get_api():
|
||||
latest_release = get_latest_release()
|
||||
cursor = conn.cursor()
|
||||
cursor.execute('SELECT api FROM apikey')
|
||||
apikey = cursor.fetchone()[0]
|
||||
@@ -117,7 +135,6 @@ def set_mailserver(server):
|
||||
print('Your mail server has been updated.')
|
||||
conn.commit()
|
||||
|
||||
|
||||
|
||||
def apikey(key):
|
||||
now = datetime.now().strftime("%m-%d-%Y %H:%M")
|
||||
@@ -126,7 +143,34 @@ def apikey(key):
|
||||
logging.info(now + ' - Info : API key updated')
|
||||
print('Your API key has been updated.')
|
||||
conn.commit()
|
||||
|
||||
|
||||
|
||||
def get_mail_domains(info):
|
||||
apikey = get_api()
|
||||
cursor = conn.cursor()
|
||||
mail_server = get_settings('mail_server')
|
||||
req = urllib.request.Request('https://'+mail_server+'/api/v1/get/domain/all')
|
||||
req.add_header('Content-Type', 'application/json')
|
||||
req.add_header('X-API-Key', apikey)
|
||||
current = urllib.request.urlopen(req)
|
||||
remote = current.read().decode('utf-8')
|
||||
remoteData = json.loads(remote)
|
||||
if info:
|
||||
total_aliases = 0
|
||||
i=0
|
||||
print('\n[b]malias[/b] - All email domains on %s' %(mail_server))
|
||||
print('==================================================================')
|
||||
for domains in remoteData:
|
||||
cursor.execute('SELECT count(*) FROM aliases where alias like ? or goto like ?', ('%'+remoteData[i]['domain_name']+'%','%'+remoteData[i]['domain_name']+'%',))
|
||||
count = cursor.fetchone()[0]
|
||||
total_aliases += count
|
||||
print('%s \t\twith %s aliases' %(remoteData[i]['domain_name'],count))
|
||||
i+=1
|
||||
print('\n\nThere is a total of %s domains with %s aliases.' %(str(i),str(total_aliases)))
|
||||
|
||||
else:
|
||||
return(remoteData)
|
||||
|
||||
|
||||
def create(alias,to_address):
|
||||
now = datetime.now().strftime("%m-%d-%Y %H:%M")
|
||||
@@ -151,7 +195,7 @@ def create(alias,to_address):
|
||||
conn.commit()
|
||||
logging.info(now + ' - Info : alias %s created for %s on the mailcow instance %s ' %(alias,to_address,server))
|
||||
print('\n[b]Info[/b] : alias %s created for %s on the mailcow instance %s \n' %(alias,to_address,server))
|
||||
|
||||
|
||||
|
||||
|
||||
def delete_alias(alias):
|
||||
@@ -184,6 +228,7 @@ def delete_alias(alias):
|
||||
|
||||
|
||||
|
||||
|
||||
def copy_data():
|
||||
apikey = get_api()
|
||||
mail_server = get_settings('mail_server')
|
||||
@@ -206,8 +251,41 @@ def copy_data():
|
||||
logging.info(now + ' - Info : aliases imported from the mailcow instance %s to local DB' %(mail_server))
|
||||
print('\n[b]Info[/b] : aliases imported from the mailcow instance %s to local DB\n' %(mail_server))
|
||||
else:
|
||||
print('\n[b]Info[/b] : aliases alreday imported from the mailcow instance %s to local DB\n' %(mail_server))
|
||||
|
||||
print('\n[b]Info[/b] : aliases alreday imported from the mailcow instance %s to local DB\n\n[i]Updating with any missing aliases![/i]' %(mail_server))
|
||||
update_data()
|
||||
|
||||
|
||||
def update_data():
|
||||
apikey = get_api()
|
||||
mail_server = get_settings('mail_server')
|
||||
if get_settings('copy_status') == 1:
|
||||
now = datetime.now().strftime("%m-%d-%Y %H:%M")
|
||||
cursor = conn.cursor()
|
||||
req = urllib.request.Request('https://'+mail_server+'/api/v1/get/alias/all')
|
||||
req.add_header('Content-Type', 'application/json')
|
||||
req.add_header('X-API-Key', apikey)
|
||||
current = urllib.request.urlopen(req)
|
||||
remote = current.read().decode('utf-8')
|
||||
remoteData = json.loads(remote)
|
||||
i = 0
|
||||
count_alias = 0
|
||||
cursor = conn.cursor()
|
||||
for data in remoteData:
|
||||
cursor.execute('SELECT count(*) FROM aliases where alias like ? and goto like ?', (remoteData[i]['address'],remoteData[i]['goto'],))
|
||||
count = cursor.fetchone()[0]
|
||||
if count >= 1 :
|
||||
i+=1
|
||||
else:
|
||||
cursor.execute('INSERT INTO aliases values(?,?,?,?)', (remoteData[i]['id'], remoteData[i]['address'],remoteData[i]['goto'],now))
|
||||
count_alias+=1
|
||||
i+=1
|
||||
conn.commit()
|
||||
if count_alias > 0:
|
||||
logging.info(now + ' - Info : Local DB updated with %s new aliases from %s ' %(str(count_alias),mail_server))
|
||||
print('\n[b]Info[/b] : Local DB update with %s new aliases from %s \n' %(str(count_alias),mail_server))
|
||||
else:
|
||||
print('\n[b]Info[/b] : No missing aliases from local DB \n')
|
||||
|
||||
|
||||
def checklist(alias):
|
||||
alias_exist = None
|
||||
@@ -235,6 +313,7 @@ def checklist(alias):
|
||||
|
||||
def list_alias():
|
||||
apikey = get_api()
|
||||
cursor = conn.cursor()
|
||||
mail_server = get_settings('mail_server')
|
||||
req = urllib.request.Request('https://'+mail_server+'/api/v1/get/alias/all')
|
||||
req.add_header('Content-Type', 'application/json')
|
||||
@@ -243,13 +322,21 @@ def list_alias():
|
||||
remote = current.read().decode('utf-8')
|
||||
remoteData = json.loads(remote)
|
||||
i = 0
|
||||
print('\n[b]malias[/b] - All aliases on %s' %(mail_server))
|
||||
print('===================================================')
|
||||
l = 0
|
||||
print('\n[b]malias[/b] - All aliases on %s ([b]*[/b] also in local db)' %(mail_server))
|
||||
print('==================================================================')
|
||||
for search in remoteData:
|
||||
the_alias = remoteData[i]['address'].ljust(20,' ')
|
||||
print(the_alias + '\tgoes to\t\t' + remoteData[i]['goto'])
|
||||
the_goto = remoteData[i]['goto'].ljust(20,' ')
|
||||
cursor.execute('SELECT count(*) FROM aliases where alias like ? or goto like ?', (remoteData[i]['address'],remoteData[i]['address'],))
|
||||
count = cursor.fetchone()[0]
|
||||
if count >= 1:
|
||||
print(the_alias + '\tgoes to\t\t' + the_goto + '\t[b]*[/b]')
|
||||
l=l+1
|
||||
else:
|
||||
print(the_alias + '\tgoes to\t\t' + the_goto)
|
||||
i=i+1
|
||||
|
||||
print('\n\nTotal number of aliases %s on instance [b]%s[/b] and %s on [b]local DB[/b].' %(str(i),mail_server,str(l)))
|
||||
|
||||
|
||||
def alias_id(alias):
|
||||
@@ -297,10 +384,11 @@ def check_local_db(alias_id):
|
||||
|
||||
|
||||
|
||||
|
||||
def search(alias):
|
||||
apikey = get_api()
|
||||
mail_server = get_settings('mail_server')
|
||||
alias_server = number_of_aliases_on_server()
|
||||
alias_db = number_of_aliases_in_db()
|
||||
cursor = conn.cursor()
|
||||
cursor.execute('SELECT data_copy FROM settings where id = 1')
|
||||
result = cursor.fetchone()[0]
|
||||
@@ -309,13 +397,14 @@ def search(alias):
|
||||
cursor.execute('SELECT * from aliases where alias like ? or goto like ?',(search_term,search_term,))
|
||||
remoteData = cursor.fetchall()
|
||||
i = 0
|
||||
print('\nAliases on %s that contains %s' %(mail_server,alias))
|
||||
print('\nAliases on %s that contains [b]%s[/b]' %(mail_server,alias))
|
||||
print('=================================================================')
|
||||
for search in remoteData:
|
||||
the_alias = remoteData[i][1].ljust(20,' ')
|
||||
print(the_alias + '\tgoes to\t\t' + remoteData[i][2])
|
||||
i=i+1
|
||||
print('\n\nData from local DB')
|
||||
|
||||
else:
|
||||
req = urllib.request.Request('https://'+mail_server+'/api/v1/get/alias/all')
|
||||
req.add_header('Content-Type', 'application/json')
|
||||
@@ -324,20 +413,44 @@ def search(alias):
|
||||
remote = current.read().decode('utf-8')
|
||||
remoteData = json.loads(remote)
|
||||
i = 0
|
||||
print('\nAliases on %s that contains %s' %(mail_server,alias))
|
||||
print('\nAliases on %s that contains [b]%s[/b]' %(mail_server,alias))
|
||||
print('=================================================')
|
||||
for search in remoteData:
|
||||
if alias in remoteData[i]['address'] or alias in remoteData[i]['goto']:
|
||||
print(remoteData[i]['address'] + '\tgoes to\t\t' + remoteData[i]['goto'])
|
||||
i=i+1
|
||||
print('\n\nData from server')
|
||||
if alias_server != alias_db:
|
||||
print('\n\nThere are %s aliases on the server and %s aliases in local DB' %(str(alias_server),str(alias_db)))
|
||||
print('Run [i]malias -c[/i] to update local DB')
|
||||
|
||||
|
||||
|
||||
|
||||
def get_mailcow_version():
|
||||
apikey = get_api()
|
||||
mail_server = get_settings('mail_server')
|
||||
req = urllib.request.Request('https://'+mail_server+'/api/v1/get/status/version')
|
||||
req.add_header('Content-Type', 'application/json')
|
||||
req.add_header('X-API-Key', apikey)
|
||||
current = urllib.request.urlopen(req)
|
||||
remote = current.read().decode('utf-8')
|
||||
remoteData = json.loads(remote)
|
||||
remote_heads = git.cmd.Git().ls_remote('https://github.com/mailcow/mailcow-dockerized', tags=True)
|
||||
tags = remote_heads.splitlines()
|
||||
for x in tags:
|
||||
string = x.rsplit('/',2)
|
||||
|
||||
if remoteData['version'] != string[2]:
|
||||
versionInfo = 'Your Mailcow version is %s and the latest is %s' %(remoteData['version'], string[2])
|
||||
else:
|
||||
versionInfo = 'You have the latest Mailcow version %s' %remoteData['version']
|
||||
|
||||
return (versionInfo)
|
||||
|
||||
|
||||
def show_current_info():
|
||||
API = get_api()
|
||||
mail_server = get_settings('mail_server')
|
||||
|
||||
latest_release = get_latest_release()
|
||||
if API == 'DUMMY_KEY':
|
||||
API = 'Missing API Key!'
|
||||
|
||||
@@ -346,16 +459,31 @@ def show_current_info():
|
||||
|
||||
aliases_server = number_of_aliases_on_server()
|
||||
alias_db = number_of_aliases_in_db()
|
||||
|
||||
mailcow_version = get_mailcow_version()
|
||||
mail_domains = get_mail_domains(False)
|
||||
domain = ""
|
||||
i=0
|
||||
for domains in mail_domains:
|
||||
if i!=0:
|
||||
domain = domain + ', ' + str(mail_domains[i]['domain_name'])
|
||||
else:
|
||||
domain = domain + str(mail_domains[i]['domain_name'])
|
||||
i+=1
|
||||
print('\n[b]malias[/b] - Manage aliases on mailcow Instance.')
|
||||
print('===================================================')
|
||||
print('API key : [b]%s[/b]' % (API))
|
||||
print('mailcow Instance : [b]%s[/b]' % (mail_server))
|
||||
print('Mailcow Instance : [b]%s[/b]' % (mail_server))
|
||||
print('Active domains : [b]%s[/b]' % (domain))
|
||||
print('Mailcow version : [b]%s[/b]' % (mailcow_version))
|
||||
print('Logfile : [b]%s[/b]' % (logfile))
|
||||
print('Databse : [b]%s[b]' % (database))
|
||||
print('Aliases on server : [b]%s[/b]' % (aliases_server))
|
||||
print('Aliases in DB : [b]%s[/b]' % (alias_db))
|
||||
print('')
|
||||
print('App version : [b]%s[/b] (https://gitlab.pm/rune/malias)' % (app_version))
|
||||
if app_version != latest_release:
|
||||
print('App version : [b]%s[/b] a new version (%s) is available @ https://iurl.no/malias' % (app_version,latest_release))
|
||||
else:
|
||||
print('App version : [b]%s[/b]' % (app_version))
|
||||
print('')
|
||||
|
||||
|
||||
@@ -384,7 +512,10 @@ parser.add_argument('-d', '--delete', help='Delete alias.\n\n',
|
||||
nargs=1, metavar=('alias@domain.com'), required=False, action="append")
|
||||
|
||||
|
||||
parser.add_argument('-v', '--version', help='Show current version and config info\n\n',
|
||||
parser.add_argument('-i', '--info', help='Show current config and appliacation info\n\n',
|
||||
required=False, action='store_true')
|
||||
|
||||
parser.add_argument('-v', '--version', help='Show current version\n\n',
|
||||
required=False, action='store_true')
|
||||
|
||||
parser.add_argument('-c', '--copy', help='Copy alias data from mailcow server to local DB.\n\n',
|
||||
@@ -393,6 +524,9 @@ parser.add_argument('-c', '--copy', help='Copy alias data from mailcow server to
|
||||
parser.add_argument('-l', '--list', help='List all aliases on the Mailcow instance.\n\n',
|
||||
required=False, action='store_true')
|
||||
|
||||
parser.add_argument('-o', '--domains', help='List all mail domains on the Mailcow instance.\n\n',
|
||||
required=False, action='store_true')
|
||||
|
||||
|
||||
args = vars(parser.parse_args())
|
||||
|
||||
@@ -406,13 +540,18 @@ elif args['add']:
|
||||
create(args['add'][0][0],args['add'][0][1])
|
||||
elif args['delete']:
|
||||
delete_alias(args['delete'][0][0])
|
||||
elif args['version']:
|
||||
elif args['info']:
|
||||
show_current_info()
|
||||
elif args['version']:
|
||||
release_check()
|
||||
elif args['copy']:
|
||||
copy_data()
|
||||
elif args['list']:
|
||||
list_alias()
|
||||
elif args['domains']:
|
||||
get_mail_domains(True)
|
||||
|
||||
|
||||
else:
|
||||
# get_api()
|
||||
print('\n\nEh, sorry! I need something more to help you! If you write [b]malias -h[/b] I\'ll show a help screen to get you going!!!\n\n\n')
|
@@ -11,7 +11,9 @@ click==8.1.3
|
||||
docopt==0.6.2
|
||||
docutils==0.19
|
||||
frozenlist==1.3.3
|
||||
gpg==1.19.0
|
||||
gitdb==4.0.10
|
||||
GitPython==3.1.32
|
||||
gpg==1.21.0
|
||||
idna==3.4
|
||||
importlib-metadata==6.1.0
|
||||
jaraco.classes==3.2.3
|
||||
@@ -36,6 +38,7 @@ requests-toolbelt==0.10.1
|
||||
rfc3986==2.0.0
|
||||
rich==13.3.1
|
||||
six==1.16.0
|
||||
smmap==5.0.0
|
||||
tqdm==4.65.0
|
||||
twine==4.0.2
|
||||
urllib3==1.26.14
|
||||
|
Reference in New Issue
Block a user