2017-10-05 23:38:33 +02:00
from flask import Flask
from flask_restful import Resource , Api
2017-10-06 10:20:40 +02:00
from flask import jsonify
2017-11-03 20:26:09 +01:00
from flask import request
2017-10-27 11:22:39 +02:00
from threading import Thread
2017-10-06 10:20:40 +02:00
import docker
2017-10-27 11:22:39 +02:00
import signal
import time
2017-12-09 13:15:24 +01:00
import os
import re
import sys
2017-10-05 23:38:33 +02:00
2017-12-01 23:41:37 +01:00
docker_client = docker . DockerClient ( base_url = ' unix://var/run/docker.sock ' , version = ' auto ' )
2017-10-05 23:38:33 +02:00
app = Flask ( __name__ )
api = Api ( app )
2017-10-06 10:20:40 +02:00
class containers_get ( Resource ) :
2017-10-27 11:22:39 +02:00
def get ( self ) :
containers = { }
2017-11-03 20:26:09 +01:00
try :
2017-12-11 09:43:01 +01:00
for container in docker_client . containers . list ( all = True ) :
2017-11-03 20:26:09 +01:00
containers . update ( { container . attrs [ ' Id ' ] : container . attrs } )
return containers
except Exception as e :
return jsonify ( type = ' danger ' , msg = e )
2017-10-05 23:38:33 +02:00
2017-10-06 10:20:40 +02:00
class container_get ( Resource ) :
2017-10-27 11:22:39 +02:00
def get ( self , container_id ) :
if container_id and container_id . isalnum ( ) :
2017-11-03 20:26:09 +01:00
try :
2017-12-11 09:43:01 +01:00
for container in docker_client . containers . list ( all = True , filters = { " id " : container_id } ) :
2017-11-03 20:26:09 +01:00
return container . attrs
except Exception as e :
return jsonify ( type = ' danger ' , msg = e )
2017-10-27 11:22:39 +02:00
else :
2017-11-03 20:26:09 +01:00
return jsonify ( type = ' danger ' , msg = ' no or invalid id defined ' )
2017-10-05 23:38:33 +02:00
2017-10-06 10:20:40 +02:00
class container_post ( Resource ) :
2017-10-27 11:22:39 +02:00
def post ( self , container_id , post_action ) :
if container_id and container_id . isalnum ( ) and post_action :
if post_action == ' stop ' :
try :
2017-12-11 09:43:01 +01:00
for container in docker_client . containers . list ( all = True , filters = { " id " : container_id } ) :
2017-10-27 11:22:39 +02:00
container . stop ( )
2017-11-03 20:26:09 +01:00
return jsonify ( type = ' success ' , msg = ' command completed successfully ' )
except Exception as e :
return jsonify ( type = ' danger ' , msg = e )
2017-10-27 11:22:39 +02:00
elif post_action == ' start ' :
try :
2017-12-11 09:43:01 +01:00
for container in docker_client . containers . list ( all = True , filters = { " id " : container_id } ) :
2017-10-27 11:22:39 +02:00
container . start ( )
2017-11-03 20:26:09 +01:00
return jsonify ( type = ' success ' , msg = ' command completed successfully ' )
except Exception as e :
return jsonify ( type = ' danger ' , msg = e )
2017-10-27 11:22:39 +02:00
elif post_action == ' restart ' :
try :
2017-12-11 09:43:01 +01:00
for container in docker_client . containers . list ( all = True , filters = { " id " : container_id } ) :
2017-10-27 11:22:39 +02:00
container . restart ( )
2017-11-03 20:26:09 +01:00
return jsonify ( type = ' success ' , msg = ' command completed successfully ' )
except Exception as e :
return jsonify ( type = ' danger ' , msg = e )
elif post_action == ' exec ' :
if not request . json or not ' cmd ' in request . json :
return jsonify ( type = ' danger ' , msg = ' cmd is missing ' )
if request . json [ ' cmd ' ] == ' sieve_list ' and request . json [ ' username ' ] :
try :
2017-12-11 09:43:01 +01:00
for container in docker_client . containers . list ( filters = { " id " : container_id } ) :
2017-11-03 20:26:09 +01:00
return container . exec_run ( [ " /bin/bash " , " -c " , " /usr/local/bin/doveadm sieve list -u ' " + request . json [ ' username ' ] . replace ( " ' " , " ' \\ ' ' " ) + " ' " ] , user = ' vmail ' )
except Exception as e :
return jsonify ( type = ' danger ' , msg = e )
elif request . json [ ' cmd ' ] == ' sieve_print ' and request . json [ ' script_name ' ] and request . json [ ' username ' ] :
try :
2017-12-11 09:43:01 +01:00
for container in docker_client . containers . list ( filters = { " id " : container_id } ) :
2017-11-03 20:26:09 +01:00
return container . exec_run ( [ " /bin/bash " , " -c " , " /usr/local/bin/doveadm sieve get -u ' " + request . json [ ' username ' ] . replace ( " ' " , " ' \\ ' ' " ) + " ' ' " + request . json [ ' script_name ' ] . replace ( " ' " , " ' \\ ' ' " ) + " ' " ] , user = ' vmail ' )
except Exception as e :
return jsonify ( type = ' danger ' , msg = e )
2017-12-09 13:15:24 +01:00
elif request . json [ ' cmd ' ] == ' worker_password ' and request . json [ ' raw ' ] :
try :
2017-12-11 09:43:01 +01:00
for container in docker_client . containers . list ( filters = { " id " : container_id } ) :
2017-12-09 13:15:24 +01:00
hash = container . exec_run ( [ " /bin/bash " , " -c " , " /usr/bin/rspamadm pw -e -p ' " + request . json [ ' raw ' ] . replace ( " ' " , " ' \\ ' ' " ) + " ' " ] , user = ' _rspamd ' )
f = open ( " /access.inc " , " w " )
f . write ( ' enable_password = " ' + re . sub ( ' [^0-9a-zA-Z \ $]+ ' , ' ' , hash . rstrip ( ) ) + ' " ; \n ' )
f . close ( )
container . restart ( )
return jsonify ( type = ' success ' , msg = ' command completed successfully ' )
except Exception as e :
return jsonify ( type = ' danger ' , msg = e )
2017-10-05 23:38:33 +02:00
else :
2017-11-03 20:26:09 +01:00
return jsonify ( type = ' danger ' , msg = ' Unknown command ' )
2017-10-27 11:22:39 +02:00
else :
2017-11-03 20:26:09 +01:00
return jsonify ( type = ' danger ' , msg = ' invalid action ' )
2017-10-27 11:22:39 +02:00
else :
2017-11-03 20:26:09 +01:00
return jsonify ( type = ' danger ' , msg = ' invalid container id or missing action ' )
2017-10-27 11:22:39 +02:00
class GracefulKiller :
kill_now = False
def __init__ ( self ) :
signal . signal ( signal . SIGINT , self . exit_gracefully )
signal . signal ( signal . SIGTERM , self . exit_gracefully )
def exit_gracefully ( self , signum , frame ) :
self . kill_now = True
def startFlaskAPI ( ) :
app . run ( debug = False , host = ' 0.0.0.0 ' , port = ' 8080 ' , threaded = True )
2017-10-05 23:38:33 +02:00
2017-10-06 10:20:40 +02:00
api . add_resource ( containers_get , ' /containers/json ' )
api . add_resource ( container_get , ' /containers/<string:container_id>/json ' )
api . add_resource ( container_post , ' /containers/<string:container_id>/<string:post_action> ' )
2017-10-05 23:38:33 +02:00
if __name__ == ' __main__ ' :
2017-10-27 11:22:39 +02:00
api_thread = Thread ( target = startFlaskAPI )
api_thread . daemon = True
api_thread . start ( )
killer = GracefulKiller ( )
while True :
time . sleep ( 1 )
if killer . kill_now :
break
print " Stopping dockerapi-mailcow "
2017-12-11 09:43:01 +01:00