#!/usr/bin/env python
# coding=utf-8
'''
Author: Logan
Date: 2020-11-20 23:16:57
LastEditTime: 2020-11-22 17:17:39
Description: xedge
curl -sk -O https://internal.up-gram.com/shell/xedge-tools.py
'''

import re
import os
import sys
import shlex
import json
import platform
import argparse
import logging
from logging.handlers import RotatingFileHandler


RENDER_HTML_TEMPLATE = """<config>
    <common>
        <logging level="3" />
        <uas enabled = "0" />
     {% if data.zone.upper() =='US'%}      
        <bt_check enabled = "2" />
     {% else %}
        <bt_check enabled = "0" />
     {% endif %}
        <bt_filter_mode mode="2" />
    </common>
    <server name="xvpn" max_connections="{{data.connection}}"  max_speed="{{data.rate}}" max_traffic="{{data.bandwidth}}" country="{{data.zone.upper()}}" dns_1="8.8.8.8" dns_2="1.1.1.1" listen_ip="{{data.ip}}" network="3" node="{{data.node}}" public_eth="{{data.interface}}" public_ip="" site="{{data.site}}" subsite="{{data.subsite}}" >
    </server>
    <processes>
        <process autostart="1" domain="public" enable="1" id="1" routing="1" type="master">
            <services comment="client-server">
                <service enable="1" name="xtunnel" net_type="tunnel" websvr_addr="http://webserver.skyvpnapi.com:8080"  mode="{{data.mode}}"  >
 {% if "ssl2" in  data.protocols  %}
              <listen protocol = "ssl2"   ip="0.0.0.0" port="443"  recv_buf="262144"  send_buf="462144" comment="ssl" />{% endif %}
 {% if "ssl" in  data.protocols  %}       
                    <listen protocol="ssl"  ip="0.0.0.0" port="443"  recv_buf="262144"  send_buf="392144"  comment="ssl"  />{% endif %}
 {% if "http" in  data.protocols  %}  
                    <listen protocol="http" ip="0.0.0.0" port="80"   recv_buf="262144"  send_buf="392144"  comment="http"  />{% endif %}
{% if "https" in  data.protocols  %}
                    <listen protocol="https" ip="0.0.0.0" port="443"   recv_buf="262144"  send_buf="392144"  comment="https"  />{% endif %}
 {% if "udp" in  data.protocols  %}                 
                    <listen protocol="udp"  port="389"  recv_buf="6291456" send_buf="6291456" comment="idap" />{% endif %}
 {% if "dns" in  data.protocols  %}  
                    <listen protocol="dns"  port="53"   recv_buf="6291456" send_buf="6291456" comment="dns"  />{% endif %}
 {% if "icmp" in  data.protocols  %} 
                    <listen protocol="icmp"   port="100"   recv_buf="6291456" send_buf="6291456" comment="icmp"  />{% endif %}
 {% if "xtcp"  in  data.protocols  %}
                    <listen  protocol="xtcp"  port="24352"  recv_buf="262144" send_buf="462144" comment="xtcp" />{% endif %}
 {% if "xudp"  in  data.protocols  %}
              <listen  protocol="xudp" port="37059" recv_buf="6291456" send_buf="6291456" comment="xudp" />{% endif %}
                </service>
            </services>
        </process>
    </processes>
</config>"""


def template(data):
    import jinja2
    res = jinja2.Template(source=RENDER_HTML_TEMPLATE).render(data=data)
    return res


class vpnhost(object):
    def __init__(self, protocols, zone, serverid, ip, floatingip=None):
        self.protocols = protocols
        self.zone = zone
        self.serverid = serverid
        self.ip = ip
        self.floatingip = floatingip

    def check_serverid(self):
        pattern = re.compile(r'\d+\.\d+\.\d+$')
        matchObj = pattern.match(self.serverid)
        if matchObj:
            return True
        else:
            return False


def file_io(path, method, content):
    """ 文件写入  """
    with open(path, method) as f:
        f.write(content)


def bash(cmd):
    """
    执行执行bash命令
    """
    logger.info(cmd)
    return shlex.os.system(cmd)


def parse_args():
    """
    获取参数
    """

    content = """xedge初始化工具 ^_^

    执行:  python tools.py  --protocols   ssl2 xtcp xudp dns http  -zone US  --serverid 31.1.1   --platform gcorelabs
        """
    parser = argparse.ArgumentParser(
        usage="tools",
        description=content,
        add_help=False,
        formatter_class=lambda prog: argparse.RawTextHelpFormatter(
            prog, max_help_position=50)
    )
    parser.add_argument("--help",
                        action="help",
                        help="查看帮助信息")
    parser.add_argument("--uninstall",
                        action="store_true",
                        help="卸载")
    parser.add_argument("-p", "--protocols",
                        nargs='+',
                        default=["ssl2", "xtcp", "xudp", "dns", "http","icmp"],
                        help="default:ssl2 xtcp xudp dns http")
    parser.add_argument('-z', '--zone',
                        help='Zone')
    parser.add_argument('-s', '--serverid',
                        help='Serverid')
    parser.add_argument('-i', '--ip',
                        default="0.0.0.0",
                        help='default:0.0.0.0')
    parser.add_argument('-f', '--floatingip',
                        help='floatingip')
    parser.add_argument('-b', '--bandwidth',
                        default='2000',
                        help='bandwidth')
    parser.add_argument('-r', '--rate',
                        default='200',
                        help='rate')
    parser.add_argument('-c', '--connection',
                        default='1000',
                        help='connection')
    parser.add_argument('--interface',
                        default='eth0',
                        help='default:eth0')
    parser.add_argument('--site',
                        help='site')
    parser.add_argument('--subsite',
                        help='subsite')
    parser.add_argument('--node',
                        help='node')
    parser.add_argument('--mode',
                        default='3',
                        help='mode')
    parser.add_argument('--platform',
                        help='Platform')

    args = parser.parse_args()
    return args


class LoggerLog:
    def __init__(self, name=__name__):
        # 创建一个loggger
        self.__name = name
        self.logger = logging.getLogger(self.__name)
        self.logger.setLevel(logging.DEBUG)

        # 创建一个handler,用于写入日志文件
        log_path = os.path.dirname(os.path.abspath(__file__))

        # os.makedirs('logs', exist_ok=True)  # 设置日志输出目录
        # logname = log_path + 'output.log'  # 指定输出的日志文件名
        # fh = logging.handlers.TimedRotatingFileHandler(logname, when='M', interval=1, backupCount=5,encoding='utf-8')  # 指定utf-8格式编码,避免输出的日志文本乱码
        logname = 'output.log'
        fh = logging.handlers.RotatingFileHandler(
            logname, maxBytes=1024*1024, backupCount=3)
        fh.setLevel(logging.DEBUG)

        # 创建一个handler,用于将日志输出到控制台
        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)
        # 定义handler的输出格式
        formatter = logging.Formatter('%(asctime)s %(name)s [line:%(lineno)d] %(levelname)s %(message)s',
                                      datefmt='%b %d  %Y %H:%M:%S')
        fh.setFormatter(formatter)
        ch.setFormatter(formatter)

        # 给logger添加handler
        self.logger.addHandler(fh)
        self.logger.addHandler(ch)

    @property
    def get_log(self):
        """定义一个函数,回调logger实例"""
        return self.logger


def pre_install():
    if platform.system() == 'Linux':
        bash("curl -s http://mirrors.aliyun.com/repo/epel-7.repo >/etc/yum.repos.d/epel-7.repo")
        bash("yum  --debuglevel=1  -y  install unzip")
       
        bash(" yum  --debuglevel=1   install  python-pip -y   &&   pip   install jinja2 requests ")
        # bash("curl  -s http://internal.up-gram.com/shell/install-py3.sh|bash")
        # bash(" pip  install -i http://mirrors.aliyun.com/pypi/simple  --trusted-host mirrors.aliyun.com  install jinja2 requests")

def reported_data(ip,platform,zone,serverid):
    
    import requests

    headers = {
            # "Content-Type": "application/x-www-form-urlencoded",
            "Content-Type": "application/json",
        }
    pdata = {
        "ip": ip,
        "sshport": "1022",
        "sshuser": "root",
        "sshkey_name": "skyvpn.pem",
        "platform": platform,
        "vpnzone": zone,
        "serverid": serverid,
        "status": "0"
        }

    data = json.dumps(pdata)
    print(data)
    #ret = requests.post(url="http://vpn.up-gram.com/api/host", data=data, headers=headers)
    #return ret


def main():
    pre_install()
    logger.info("[\033[1;32m 安装依赖环境包 \033[0m]  ...")

    # bash("curl -k  -u admin:wxY8fk1#   -O https://ops.up-gram.com/xedge/install-xedge-vpn.zip")
    bash("curl -sL -O http://internal.up-gram.com/xedge/install-xedge-vpn.zip")
    logger.info("[\033[1;32m 下载xedge压缩文件 \033[0m]  ...")

    bash("unzip install-xedge-vpn.zip && sudo ./init-vpn-instance.sh")
    logger.info("[\033[1;32m init-vpn-instance 执行完毕 \033[0m]  ...")

    bash("curl -s http://internal.up-gram.com/shell/update-xedge.sh|bash")
    bash("chmod  755 /usr/local/dingtone/xedge")
    logger.info("[\033[1;32m 替换最新xedge文件 \033[0m]")

    bash("./check-vpn-instance.sh")
    logger.info("[\033[1;32m check-vpn-instance 执行完毕 \033[0m]  ...")

    bash("curl -s  http://internal.up-gram.com/shell/ssh-keys.sh |bash")
    logger.info("[\033[1;32m 推送ssh-key 执行完毕 \033[0m]  ...")
    


if __name__ == '__main__':
    logger = LoggerLog("Tools").get_log

    if len(sys.argv) == 1:
        """ 如果没有传参则打印帮助信息 """
        sys.argv.append("--help")
        args = parse_args()
        sys.exit(1)

    args = parse_args()
    # print(args.protocols, args.zone.upper(), args.serverid,
    #       args.ip, args.rate, args.bandwidth)

    if args.uninstall:
        logger.info(
            "[\033[1;32mxdege卸载文件\033[0m]")
        bash("pkill xedge")
        bash("rm -rf /usr/local/dingtone /var/log/dingtone /etc/dingtone")
        bash("rm -f  /etc/rc.d/init.d/dingtone-xedge")
        bash("ls /root/* |grep -v py|xargs rm -f")
        sys.exit(1)
    else:
        # 执行xdege sh脚本
        main()
        # instance
        host = vpnhost(args.protocols, args.zone,
                       args.serverid, args.ip)
        # check serverid
        if host.check_serverid():
            #  site subsite node
            server = args.serverid.split(".")
            args.site = server[0]
            args.subsite = server[1]
            args.node = server[2]
            print("check_serverid ok")
            print('Protocols:', args.protocols)
            tmp = template(args)

            file_io("/etc/dingtone/xedge-config.xml", 'w', tmp)
            logger.info(
                "[\033[1;32m更新: /etc/dingtone/xedge-config.xml \033[0m]  ...")
            

            ret = reported_data(args.ip,args.platform,args.zone,args.serverid)
            info = "[\033[1;32m上报数据: {} \033[0m]".format(ret)
            logger.info(info)

            logger.info("[\033[1;32mreboot重启主机 \033[0m]")
            bash("reboot")
        else:
            print("serverid error")
            sys.exit(1)