python SocketServer StreamRequestHandler 实例

#!/usr/bin/python
# Description : Virtual Host Manage Script

# Below is the json format description:
# 1. Add new user
# {"website":"www.baidu.com", "ftp":["user","passwd"], "mysql":["db_name","m_user","m_passwd"]}

# 2. Enable/Disable 1 (0=disable, 1=enable)
# {"manage":{"website":["www.baidu.com",0], "ftp":["user",1], "mysql":["m_user", "db_name",1]}}

# 3. Modify password for [ftp/mysql] (if you only modify ftp,then set mysql items "")
# {"ftp":["789","789", "new_passwd"], "mysql":["","","", ""]}

# 4. Restart Service for apache/ftp/mysql 1 (0=stop,1=start,2=restart)
# {"service":{"apache":1, "ftp":0, "mysql":0}}

# 5. Add/Delete/Modify/Query apache ServerAlias (Add=1,Delete=2,Modify=3,Query=4)
# {"alias":["zhuzusong.com","1","www.baidu.com www.iciba.com"]}

import os
import time
import subprocess
import SocketServer
import MySQLdb
import simplejson as json

class Add_User(SocketServer.StreamRequestHandler):

    def setup(self):
        self.connection           = self.request
        self.rfile                = self.connection.makefile('rb', self.rbufsize)
        self.wfile                = self.connection.makefile('wb', self.wbufsize)
        self.Error                = []
        self.Error_log            = '/tmp/Add_User_%s.log' %(time.strftime('%Y%m%d'))
        self.apache_document_root = '/data/www'
        self.vhost_conf           = '/etc/httpd/conf.d'
        self.vuser_list           = '/etc/vsftpd/vsftpd_login.txt'
        self.vuser_conf           = '/etc/vsftpd/vuser_conf'

    def add_mysql_account(self, mysql_db, mysql_user, mysql_passwd):
        try:
            conn=MySQLdb.connect(host='localhost',port=3306,user='root',passwd='123ewq')
            cursor = conn.cursor()
            rownumber = cursor.execute('select User from mysql.user where User="%s"' %mysql_user)
            # make sure the mysql login username is unique !
            assert cursor.rowcount == 0, 'mysql account %s is exist' %mysql_user

            cursor.execute('create database %s' %mysql_db)
            cursor.execute('grant all privileges on %s.* to "%s"@"%%" identified by "%s"' \
                            %(mysql_db, mysql_user, mysql_passwd))
            cursor.close()
            conn.close()
        except Exception, error:
            self.Error.append("Function(add_mysql_account) Error : %s" %error)

    def del_mysql_account(self, mysql_db, mysql_user):
        try:
            conn=MySQLdb.connect(host='localhost',port=3306,user='root',passwd='123ewq')
            cursor = conn.cursor()
            cursor.execute('drop database %s' %mysql_db)
            cursor.execute('DELETE FROM mysql.user WHERE USER="%s" AND HOST="%%"' %mysql_user)
            cursor.execute('DELETE FROM mysql.db WHERE USER="%s" AND db="%s"' %(mysql_user, mysql_db)) 
            cursor.execute('flush privileges')
            cursor.close()
            conn.close()
        except Exception, error:
            self.Error.append("Function(del_mysql_account) Error : %s" %error)

    def add_apache_vhost(self, website):
        apache_document_root = self.apache_document_root
        vhost_conf = self.vhost_conf

        vhost_conf_template = '''<VirtualHost *:80>
ServerName %s
DocumentRoot %s/%s
ServerAlias %s
DirectoryIndex default.htm  default.html  default.php  index.htm  index.html  index.php
php_admin_value open_basedir "%s/%s:/tmp"
<IfModule bw_mod.c>
BandWidthModule On
BandWidth all 4194304
MaxConnection all 500
</IfModule>
<Directory %s/%s>
AllowOverride All
Options +Includes
</Directory>
</VirtualHost>''' %(website, apache_document_root, website, website, apache_document_root, website, apache_document_root, website)
        
        if os.path.isfile('%s/%s' %(vhost_conf, website)):
            self.Error.append("vhost %s is exist" %website)
        else:
            try:
                fd_vhost = open('%s/%s' %(vhost_conf, website), 'w')
                fd_vhost.writelines(vhost_conf_template)
                fd_vhost.close()
                os.system('service httpd reload > /dev/null')
            except Exception, error:
                self.Error.append("Function(add_apache_vhost) Error : %s" %error)

    def del_apache_vhost(self, website):
        try:
            vhost_conf = self.vhost_conf
            os.remove('%s/%s' %(vhost_conf, website))
        except OSError,error:
            self.Error.append("Function(del_apache_vhost) Error:" %error)

    def add_ftp_account(self, website, ftp_user, ftp_passwd):
        vuser_list = self.vuser_list
        vuser_conf = '%s/%s' %(self.vuser_conf, ftp_user)
        apache_document_root = self.apache_document_root

        vuser_conf_template = '''guest_enable=YES
guest_username=vuser
local_root=%s/%s
write_enable=yes
anon_world_readable_only=YES
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES''' %(apache_document_root, website)
        
        if os.path.isfile(vuser_conf):
            self.Error.append("FTP account %s is exist" %ftp_user)
        else:
            try:
                fd1 = open(vuser_conf,'w')
                fd1.writelines(vuser_conf_template)
                os.system('mkdir -p %s/%s' %(apache_document_root, website))
                os.system('chmod 570 %s/%s' %(apache_document_root, website))
                os.system('chown apache:vuser %s/%s' %(apache_document_root, website))
                fd1.flush()
                fd1.close()

                fd2 = open(vuser_list, 'a')
                fd2.write(ftp_user + '\n')
                fd2.write(ftp_passwd + '\n')
                fd2.flush()
                fd2.close()
                cmd = '/usr/bin/db_load -T -t hash -f %s "/etc/vsftpd/vsftpd_login.db"' %(vuser_list)
                status = subprocess.Popen(cmd, shell=True,stderr = subprocess.PIPE)
            except Exception,error:
                self.Error.append("Function(add_ftp_account) Error : %s" %error)

    def del_ftp_account(self, ftp_user, ftp_passwd):
        vuser_list = self.vuser_list
        vuser_conf = '%s/%s' %(self.vuser_conf, ftp_user)
        os.remove(vuser_conf)
        os.system("/bin/sed -i 'N;/%s\n%s/d' %s" %(ftp_user, ftp_passwd, vuser_list))

    def enable_website(self, website):
        vhost_conf = self.vhost_conf
        cmd = 'mv %s/../disabled_website/%s %s/' %(vhost_conf, website, vhost_conf)
        os.system(cmd)
        os.system('service httpd reload > /dev/null')

    def disable_website(self, website):
        vhost_conf = self.vhost_conf
        cmd = 'mv %s/%s %s/../disabled_website/' %(vhost_conf, website, vhost_conf)
        os.system(cmd)
        os.system('service httpd reload > /dev/null')

    def enable_ftp(self,ftp_user):
        cmd = 'mv %s/../vuser_disable/%s %s' %(self.vuser_conf, ftp_user, self.vuser_conf)
        os.system(cmd)

    def disable_ftp(self,ftp_user):
        vuser_conf = '%s/%s' %(self.vuser_conf, ftp_user)
        cmd = 'mv %s %s/../vuser_disable/' %(vuser_conf, self.vuser_conf)
        os.system(cmd)

    def enable_mysql(self, mysql_db, mysql_user):
        conn=MySQLdb.connect(host='localhost',port=3306,user='root',passwd='123ewq')
        cursor = conn.cursor()
        sql1 = 'update mysql.user set host="%%" where user="%s"' %(mysql_user)
        sql2 = 'update mysql.db set host="%%" where user="%s" and db="%s"' %(mysql_user, mysql_db)
        sql3 = 'flush privileges'
        ret = cursor.execute(sql1)
        ret = cursor.execute(sql2)
        ret = cursor.execute(sql3)
        cursor.close()
        conn.close()

    def disable_mysql(self, mysql_db, mysql_user):
        conn=MySQLdb.connect(host='localhost',port=3306,user='root',passwd='123ewq')
        cursor = conn.cursor()
        sql1 = 'update mysql.user set host="localhost" where user="%s"' %(mysql_user)
        sql2 = 'update mysql.db set host="localhost" where user="%s" and db="%s"' %(mysql_user, mysql_db)
        sql3 = 'flush privileges'
        ret = cursor.execute(sql1)
        ret = cursor.execute(sql2)
        ret = cursor.execute(sql3)
        cursor.close()
        conn.close()
    
    def modify_ftp_passwd(self, ftp_user, old_passwd, new_passwd):
        check_passwd = 'no'
        vuser_list = self.vuser_list
        f = open(vuser_list)
        while True:
            f_ftp_user = f.readline().strip('\n')
            f_old_passwd = f.readline().strip('\n')
            if f_ftp_user != '' or f_old_passwd != '':
                if ftp_user == f_ftp_user:
                    if old_passwd == f_old_passwd:
                        check_passwd = 'yes'
                        break
                    else:
                        self.Error.append("ftp password does not match: %s" %ftp_user)
            else:
                break
        f.close()
        if check_passwd == 'yes':
            cmd1 = "/bin/sed -i '/%s/{n;s/%s/%s/}' %s" %(f_ftp_user, f_old_passwd, new_passwd, vuser_list)
            cmd2 = '/usr/bin/db_load -T -t hash -f %s "/etc/vsftpd/vsftpd_login.db"' %(vuser_list)
            os.system(cmd1)
            os.system(cmd2)

    def modify_mysql_passwd(self, mysql_db, mysql_user, old_passwd, new_passwd):
        try:
            # verify mysql_user passwd
            conn=MySQLdb.connect(host='localhost',port=3306,user='root',passwd='123ewq')
            cursor = conn.cursor()
            sql1 = 'select password from mysql.user where user="%s"' %mysql_user
            sql2 = 'select password("%s")' %old_passwd
            cursor.execute(sql1)
            store_password = cursor.fetchall()[0][0]
            cursor.execute(sql2)
            old_passwd = cursor.fetchall()[0][0]
            if old_passwd == store_password:
                # verified ok then modify the passwd
                sql3 = 'update mysql.user set password=PASSWORD("%s") where user="%s"' %(new_passwd, mysql_user)
                sql4 = 'flush privileges'
                ret = cursor.execute(sql3)
                ret = cursor.execute(sql4)
                cursor.close()
                conn.close()
            else:
                self.Error.append("mysql password does not match: %s" %mysql_user)
        except Exception, error:
            self.Error.append("Function(modify_mysql_passwd) Error: %s" %error)

    def handle(self):
        self.data = self.rfile.readline().strip()
        if self.data:
            try:
                recv_data    = json.loads(self.data)
            except Exception,error:
                self.Error.append("Json Error : %s" %error)

            if len(recv_data) == 3:
                # for add_function
                try:
                    website      = recv_data['website']
                    ftp_user     = recv_data['ftp'][0]
                    ftp_passwd   = recv_data['ftp'][1]
                    mysql_db     = recv_data['mysql'][0]
                    mysql_user   = recv_data['mysql'][1]
                    mysql_passwd = recv_data['mysql'][2]

                    self.add_mysql_account(mysql_db, mysql_user, mysql_passwd)
                    self.add_apache_vhost(website)
                    self.add_ftp_account(website, ftp_user, ftp_passwd)
                except Exception,error:
                    self.Error.append('handle(add) error: %s' %error)

                # when the three function add_* run error, then clean data
                if self.Error:
                    n = 0
                    for e in self.Error:
                        if e.find('add_mysql_account') > 0:
                            n += 1
                    if n == 0:
                        self.del_mysql_account(mysql_db, mysql_user)
                        self.del_apache_vhost(website)
                        self.del_ftp_account(ftp_user, ftp_passwd)
                    else:
                        self.del_apache_vhost(website)
                        self.del_ftp_account(ftp_user, ftp_passwd)

            elif len(recv_data) == 2:
                # for modify ftp/mysql passwd
                try:
                    ftp_user         = recv_data['ftp'][0]
                    ftp_old_passwd   = recv_data['ftp'][1]
                    ftp_new_passwd   = recv_data['ftp'][2]
                    mysql_db         = recv_data['mysql'][0]
                    mysql_user       = recv_data['mysql'][1]
                    mysql_old_passwd = recv_data['mysql'][2]
                    mysql_new_passwd = recv_data['mysql'][3]

                    if ftp_user != '':
                        self.modify_ftp_passwd(ftp_user, ftp_old_passwd, ftp_new_passwd)
                    if mysql_db != '':
                        self.modify_mysql_passwd(mysql_db, mysql_user, mysql_old_passwd, mysql_new_passwd)
                except Exception,error:
                    self.Error.append('handle(modify) error: %s' %error)

            elif len(recv_data) == 1:
                if recv_data.keys() == ['manage']:
                    # for manage [website,ftp,mysql] [enable,disable]
                    try:
                        m_data        = recv_data['manage']
                        website       = m_data['website'][0]
                        website_stats = m_data['website'][1]
                        ftp_user      = m_data['ftp'][0]
                        ftp_stats     = m_data['ftp'][1]
                        mysql_user    = m_data['mysql'][0]
                        mysql_db      = m_data['mysql'][1]
                        mysql_stats   = m_data['mysql'][2]

                        if website_stats == 0:
                            self.disable_website(website)
                        elif website_stats == 1:
                            self.enable_website(website)
                        if ftp_stats == 0:
                            self.disable_ftp(ftp_user)
                        elif ftp_stats == 1:
                            self.enable_ftp(ftp_user)
                        if mysql_stats == 0:
                            self.disable_mysql(mysql_db, mysql_user)
                        elif mysql_stats == 1:
                            self.enable_mysql(mysql_db, mysql_user)

                    except Exception,error:
                        self.Error.append('handle(manage) error: %s' %error)

                elif recv_data.keys() == ['service']:
                    # for service [ftp/mysql/apache] [start/stop/restart]
                    try:
                        s_data        = recv_data['service']
                        apache_status = s_data['apache']
                        ftp_status    = s_data['ftp']
                        mysql_status  = s_data['mysql']

                        if apache_status == 0:
                            os.system('service httpd stop > /dev/null')
                        elif apache_status == 1:
                            os.system('service httpd start > /dev/null')
                        elif apache_status == 2:
                            os.system('service httpd restart > /dev/null')
                        if ftp_status == 0:
                            os.system('service vsftpd stop > /dev/null')
                        elif ftp_status == 1:
                            os.system('service vsftpd start > /dev/null')
                        elif ftp_status == 2:
                            os.system('service vsftpd restart > /dev/null')
                        if mysql_status == 0:
                            os.system('service mysqld stop > /dev/null')
                        elif mysql_status == 1:
                            os.system('service mysqld start > /dev/null')
                        elif mysql_status == 2:
                            os.system('service mysqld restart > /dev/null')
                        
                    except Exception,error:
                        self.Error.append('handle(service) error: %s' %error)

                elif recv_data.keys() == ['alias']:
                    # for add/delete/modify/query apache ServerAlias
                    try:
                        alias_data   = recv_data['alias']
                        website      = alias_data[0]
                        signal       = int(alias_data[1])
                        server_alias = alias_data[2]
                        website_path = self.vhost_conf + '/' + website

                        if os.path.isfile(website_path):
                            if signal == 4:
                                cmd = "/bin/egrep '#?ServerAlias' %s" %website_path
                                p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
                                result = p.stdout.read()
                                # return ServerAlias
                                self.Error.append(' '.join(result.split()[1:]))
                            else:
                                cmd = "/bin/sed -i '/#\{0,1\}ServerAlias/c\ServerAlias %s' %s" %(server_alias, website_path)
                                os.system(cmd)
                        else:
                            self.Error.append('handle(alias) error: no such website %s' %website)
                    except Exception,error:
                        self.Error.append('handle(alias) error: %s' %error)

            else:
                self.Error.append('Json data error')
            
            self.wfile.write(json.dumps(self.Error))
            fd = open(self.Error_log,'a')
            fd.write('%s %s %s\n' %(time.strftime('%Y-%m-%d %H:%M:%S'), self.data, self.Error))
            fd.close()

if __name__ == '__main__':
    HOST, PORT = '', 4444
    server = SocketServer.ThreadingTCPServer((HOST, PORT),Add_User)
    server.serve_forever()

  

原文地址:https://www.cnblogs.com/txwsqk/p/2909546.html