# -*- coding: utf-8 -*-
import sys, os, requests
from threadpool import makeRequests, ThreadPool
from paramiko import AutoAddPolicy, SSHClient, SFTPClient
from scp import SCPClient
from os import listdir
from os.path import isfile, join
from pathlib import Path

class SShMulti:
    def hanlde_callback(self, request, result):
        req = request.args[0]
        print('hostname: %s - result: %s' % (req['hostname'], str(result)))

    def hanlde_callback_single(self, ecs, result):
        print('hostname: %s - result: %s' % (ecs['hostname'], str(result)))

    def ssh_upload(self, ecs, timeout = 500):
        try:
            local_file = ecs['local']
            remote_file = ecs['remote']
            ssh = SSHClient()
            ssh.set_missing_host_key_policy(AutoAddPolicy())
            ssh.connect(hostname=ecs['ip'], port=ecs.get('port', 22), username=ecs['user'], password=ecs['password'], timeout=timeout)
            if ecs['cmd'] is not None:
                ssh.exec_command(ecs['cmd'])

            with SCPClient(ssh.get_transport()) as scp:
                local_file = Path(local_file)
                if local_file.is_dir():
                    local_file = str(local_file)
                    file_list = [f for f in listdir(local_file) if isfile(join(local_file, f))]
                    files = []
                    for file in file_list:
                        files.append(local_file + '/' + file)
                    scp.put(files, remote_file)
                elif local_file.is_file():
                    scp.put(local_file, remote_file)
                else:
                    print('%s is not file or dir' % local_file)
            ssh.close()
            return True
        except Exception as e:
            print(e)
            return False

    def mutil_upload(self, ecs_list, callback = None):
        if callback is None:
            callback = self.hanlde_callback
        pool = ThreadPool(50)
        requests = makeRequests(self.ssh_upload, ecs_list, callback)
        [pool.putRequest(req) for req in requests]
        pool.wait()

    def single_upload(self, ecs_list):
        for ecs in ecs_list:
            self.ssh_upload(ecs)
            
    def mutil_exec(self, ecs_list, callback = None):
        if callback is None:
            callback = self.hanlde_callback

        pool = ThreadPool(50)
        requests = makeRequests(self.exec_ssh_cmd, ecs_list, callback)
        [pool.putRequest(req) for req in requests]
        pool.wait()

    def mutil_proxy_ping(self, proxy_list, callback = None):
        if callback is None:
            callback = self.hanlde_callback

        pool = ThreadPool(50)
        requests = makeRequests(self.proxy_ping, proxy_list, callback)
        [pool.putRequest(req) for req in requests]
        pool.wait()

    def proxy_ping(self, proxy):
        proxies = {
        "http": "http://%s:%s@%s:%s" % (proxy['username'], proxy['passwd'], proxy['ip'], proxy['port'])
        }
        g = requests.get("https://www.baidu.com/robots.txt", proxies=proxies)
        return g.status_code

    def single_exec(self, esc_list, callback = None):
        if callback is None:
            callback = self.hanlde_callback_single

        for tmp_esc in esc_list:
            result = self.exec_ssh_cmd(tmp_esc)
            callback(tmp_esc, result)

    def exec_cmd(self, ecs, timeout = 300):
        ssh = SSHClient()
        ssh.set_missing_host_key_policy(AutoAddPolicy())

        ssh.connect(hostname=ecs['ip'], port=ecs.get('port', 22), username=ecs['user'], password=ecs['password'], timeout=timeout, allow_agent=False)
        a = ssh.exec_command(command=ecs['cmd'], timeout=timeout)
        stdin, stdout, stderr = a
        ret = ' '.join(stdout.readlines())
        ssh.close()

    def exec_ssh_cmd(self, ecs, timeout = 300):
        try:
            ssh = SSHClient()
            ssh.set_missing_host_key_policy(AutoAddPolicy())

            ssh.connect(hostname=ecs['ip'], port=ecs.get('port', 22), username=ecs['user'], password=ecs['password'], timeout=timeout, allow_agent=False)
            a = ssh.exec_command(command=ecs['cmd'], timeout=timeout)
            stdin, stdout, stderr = a
            ret = ' '.join(stdout.readlines())
            ssh.close() 
            return ret
        except:
            print('exec hostname %s fail' % ecs['hostname'])
            raise

    def get_ips_map(self, filePath):
        ipsMap = {}
        with open(filePath, 'r', encoding='utf-8', newline='') as f:
            for line in f:
                if len(line.strip()) <= 0:
                    continue
                if line.startswith('#'):
                    continue
                host_arr = line.split('|')
                if len(host_arr) < 5:
                    continue

                host_arr = [one.strip() for one in host_arr]
                if len(host_arr) == 5:
                    env, module, hostname, ip, intraIp = host_arr

                if len(host_arr) == 6:
                    env, module, hostname, ip, intraIp, port = host_arr

                uniqueKey = '%s_%s' % (env, hostname)

                host = {'hostname': hostname, 'ip': ip, 'intraIp': intraIp}

                if env not in ipsMap.keys():
                    ipsMap[env] = {}

                if uniqueKey not in ipsMap[env].keys():
                    ipsMap[env][uniqueKey] = []

                ipsMap[env][uniqueKey] = host

        return ipsMap

def callback_after_avg(request, ret):
    req = request.args[0]
    if ret is False:
        print('hostname: %s - result: %s' % (req['hostname'], str(ret)))
        return 

    ret = str(ret)
    ret_list = ret.split(' ')
    avg = float(ret_list[0])
    if avg > 5:
        print('hostname: %s - result: %s' % (req['hostname'], str(ret_list[0])))

if __name__ == "__main__":
    ### node video 机器： jc-honor-sc221 ~ jc-honor-sc 239 ####
    #cmd = '/usr/bin/pm2 restart /alidata/www/node-video/process.json'
    # cmd = '/usr/bin/pm2 start /alidata/www/node-video/process.json'
    #cmd = "sed -i '$ i\/usr/bin/pm2 start /alidata/www/node-video/process.json' /etc/rc.local"
    # cmd = 'pm2 restart node-video'

    #cmd = "sed -i '$ i\/usr/bin/pm2 start /alidata/www/proxy-center/app/views/static/js/match_cat_pm2.json' /etc/rc.local"
    #cmd = '/usr/bin/pm2 restart /alidata/www/proxy-center/app/views/static/js/match_cat_pm2.json'
    ##cmd = 'pm2 restart nodejs-match-cat'

    cmd = "sed -i '$ i\/usr/bin/pm2 start /alidata/www/node-ms-cloud/pm2.config.json' /etc/rc.local"

    #cmd = 'cd /alidata/server/node/lib/ && npm install express request -g'
    # cmd = 'apt-get update && apt install software-properties-common -y &&  add-apt-repository ppa:jonathonf/ffmpeg-4 -y &&  apt-get update && apt-get install ffmpeg -y && ffmpeg -version'
    ## cmd = 'cd ~ && rm -rf init-cert.php && wget http://ae-rt.oss-cn-beijing.aliyuncs.com/ops/init-cert.php && cd ~ && /alidata/server/php/bin/php init-cert.php'
    ## cmd = 'cd ~ && /alidata/server/php/bin/php init-cert.php'
    # cmd = 'wget -qO- http://ae-rt.oss-cn-beijing.aliyuncs.com/ops/init-91ms.sh | /bin/bash >> ~/init-91ms.log;'
    #cmd = 'wget -qO- http://ae-rt.oss-cn-beijing.aliyuncs.com/ops/init-ai_ps.sh | /bin/bash >> ~/init-ai_ps.log;'
    #cmd = "kill -9 $(ps -ef | awk '/ai_ps\/matting/{print $2}') && supervisorctl status"
    #cmd = 'supervisord -c /etc/supervisor/supervisord.conf && supervisorctl status '
    #cmd = 'supervisorctl status'
    #cmd = 'netstat -nalp | grep 8899 | wc -l'
    #cmd = 'sysctl -a|grep net.ipv4.tcp_tw_reuse'
    #cmd = 'echo net.ipv4.tcp_tw_reuse = 1 > /etc/sysctl.conf && /sbin/sysctl -p && sysctl -a|grep net.ipv4.tcp_tw_reuse'
    #cmd = 'echo net.ipv4.tcp_tw_recycle = 1 > /etc/sysctl.conf && /sbin/sysctl -p && sysctl -a|grep net.ipv4.tcp_tw_recycle'
    #cmd = "cd /alidata/server/httpd/conf/extra && mv httpd-ssl.conf  httpd-ssl.conf_backup && wget http://ae-rt.oss-cn-beijing.aliyuncs.com/ops/cert/httpd-ssl.conf"
    ## cmd ="/etc/init.d/httpd -k graceful"
    ## cmd = 'cd /alidata/server/httpd/conf/vhosts && rm -rf nt.conf && wget http://ae-rt.oss-cn-beijing.aliyuncs.com/ops/conf/nt.conf'
    ##cmd = 'hostname > /alidata/server/rsync/rsyncd.motd'
    ##cmd = 'cat  /alidata/server/rsync/rsyncd.motd'
    #cmd = 'cd ~ && mkdir -p /alidata/server/httpd/conf/cert/fb.dd.chengji-inc.com_apache'
    #cmd = 'cat /proc/loadavg'

    local_file = "/alidata/cert/fb.tbk.taobaike.com/"
    remote_file = "/alidata/server/httpd/conf/cert/fb.tbk.taobaike.com/"
    cmd = 'mkdir -p %s' % remote_file
    #cmd = "echo 'Include /alidata/server/httpd/conf/ssh_vhosts/*.conf' >> /alidata/server/httpd/conf/extra/httpd-ssl.conf"
    #cmd = 'mkdir -p  /alidata/server/httpd/conf/ssh_vhosts/'
    #cmd = 'wget -qO- http://ae-rt.oss-cn-beijing.aliyuncs.com/ops/ssl_vhost.sh | /bin/bash >> ~/init-ssh.log;'
    #cmd = 'wget -qO- http://ae-rt.oss-cn-beijing.aliyuncs.com/ops/init-sms-center.sh | /bin/bash'
    #cmd = '/etc/init.d/httpd -k graceful'
    #cmd = 'echo '127.0.0.1' $HOSTNAME >> /etc/hosts'
    cmd = '''
cat > /alidata/server/httpd/conf/ssl_vhosts/mtdz.conf <<EOF
<VirtualHost *:443>
        ServerName mtdz.jiancent.com
        DocumentRoot /alidata/www/honor-mt
        <Directory "/alidata/www/honor-mt">
            Options Indexes FollowSymLinks
            AllowOverride all
            Order allow,deny
            Allow from all
        </Directory>
        SSLEngine on
        SSLCertificateFile /alidata/server/httpd/conf/cert/_jiancent.com/4618821__jiancent.com_public.crt
        SSLCertificateKeyFile /alidata/server/httpd/conf/cert/_jiancent.com/4618821__jiancent.com.key
        SSLCertificateChainFile /alidata/server/httpd/conf/cert/_jiancent.com/4618821__jiancent.com_chain.crt
        ErrorLog "|/usr/local/sbin/cronolog /alidata/log/httpd/mtdz_error_%Y_%m_%d"
        CustomLog "|/usr/local/sbin/cronolog /alidata/log/httpd/mtdz_access_%Y_%m_%d" crono_combined
</VirtualHost>
EOF
cat > /alidata/server/httpd/conf/vhosts/mtdz.conf <<EOF
<VirtualHost *:80>
        ServerName mtdz.jiancent.com
        DocumentRoot /alidata/www/honor-mt
        <Directory "/alidata/www/honor-mt">
            Options Indexes FollowSymLinks
            AllowOverride all
            Order allow,deny
            Allow from all
        </Directory>
        ErrorLog "|/usr/local/sbin/cronolog /alidata/log/httpd/mtdz_error_%Y_%m_%d"
        CustomLog "|/usr/local/sbin/cronolog /alidata/log/httpd/mtdz_access_%Y_%m_%d" crono_combined
</VirtualHost>
EOF
    '''
    ssh2 = SShMulti()
    file_path = os.path.dirname(sys.argv[0]) + '/hosts-ssh-i.txt'
    ipsMap = ssh2.get_ips_map(file_path)
    ips = ipsMap['real']
    ecs_list = []
    #cmd = "sed -i 's/;opcache.memory_consumption=64/opcache.memory_consumption=128/g' /alidata/server/php/etc/php.ini"
    #cmd = "sed -i 's/;opcache.fast_shutdown=1/opcache.fast_shutdown=1/g' /alidata/server/php/etc/php.ini"
    #cmd = "cat /alidata/server/php/etc/php.ini | grep fast_shutdown"
    #cmd = '/etc/init.d/httpd -k graceful'
    ##cmd = 'crontab -l | { cat; echo -e ""; echo "*/1 * * * * /alidata/server/php/bin/php /alidata/www/honor-mt/shell/timer_trigger_zc.php >> /alidata/log/crontab/honor_mt_timer_trigger.log 2>&1"; } | crontab -'
    cmd = 'supervisord -c /etc/supervisor/supervisord.conf && supervisorctl status'
    for key in ips:
        ecs = ips[key]
        # ecs['password'] = 'Az%CKdz22@i383#I#Z5L@u'
        ecs['password'] = 'I3$i8238*^##O3zxZ5L@u'  # ms
        # ecs['password'] = 'e23dP@U2M%Es!4' #ntms
        # ecs['password'] = '32@da9$U#HGl5L@u' #tbms
        # ecs['password'] = 'LI#KU50lk#&%0->#la' #1688
        # ecs['password'] = '8lIO@ILi7*&@(kx)8^hyl'
        # ecs['password'] = 'E$#LKIiksrt#kx$3I8'
        # ecs['user'] = 'ubuntu'
        # ecs['password'] = 'HLWQtsK#u3y*#Zta' #erp-px

        ecs['local'] = local_file
        ecs['remote'] = remote_file
        ecs['user'] = 'root'
        ecs['cmd'] = cmd
        ecs_list.append(ecs)
    ssh2.mutil_exec(ecs_list)
