| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| import json |
| import os |
| import sys |
| import re |
| import time |
| from datetime import datetime, timedelta |
|
|
| if "/www/server/panel/class" not in sys.path: |
| sys.path.insert(0, "/www/server/panel/class") |
|
|
| import public |
| from btdockerModel import dk_public as dp |
| from mod.project.docker.sites.base import Sites |
|
|
|
|
| class SitesManage(Sites): |
|
|
| def __init__(self): |
| super(SitesManage, self).__init__() |
| self.enable_php_template = ''' |
| location ~ [^/]\.php(/|$) {{ |
| if (!-f $document_root$fastcgi_script_name) {{ |
| return 404; |
| }} |
| fastcgi_pass 127.0.0.1:{port}; |
| include fastcgi.conf; |
| include fastcgi_params; |
| fastcgi_index index.php; |
| |
| set $real_script_name $fastcgi_script_name; |
| if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {{ |
| set $real_script_name $1; |
| set $path_info $2; |
| }} |
| fastcgi_param SCRIPT_FILENAME $document_root$real_script_name; |
| fastcgi_param SCRIPT_NAME $real_script_name; |
| fastcgi_param PATH_INFO $path_info; |
| }}''' |
|
|
|
|
| |
| def run_php(self, get): |
| ''' |
| @name 运行指定php环境 |
| ''' |
| |
| from btdockerModel.dockerSock import image |
| sk_image = image.dockerImage() |
| img_inspect = sk_image.inspect(get.name) |
| if not img_inspect: |
| return public.returnResult(False, msg="未找到指定的php环境镜像!") |
|
|
| |
| from mod.project.docker.runtime.runtimeManage import RuntimeManage |
| runtimeManage = RuntimeManage() |
| run_result = runtimeManage.run_php_project(get) |
| if not run_result["status"]: return run_result |
|
|
| return public.returnResult(True) |
|
|
| |
| def get_site_list(self, get): |
| ''' |
| @name 获取所有Docker网站项目列表 |
| ''' |
| get.type = get.get("type", "all") |
| if not get.type in ("php", "java", "go", "python", "proxy", "app", "all","nodejs"): |
| return public.returnResult(False, msg="type仅支持php、java、go、python、proxy、app、all") |
|
|
| if not os.path.exists("{}/synced_docker_sites.pl".format(self.sites_config_path)): |
| args = public.dict_obj() |
| self.sync_docker_sites(args) |
|
|
| if not os.path.exists("{}/init_exts_templates.pl".format(self.sites_config_path)): |
| exts = dp.sql("ext_templates").select() |
| if not exts: |
| from mod.project.docker.runtime.runtimeManage import RuntimeManage |
| runtimeManage = RuntimeManage() |
| runtimeManage.download_templates() |
| runtimeManage.add_default_php_ext_template() |
| public.writeFile("{}/init_exts_templates.pl".format(self.sites_config_path), "init exts templates") |
|
|
| get.query = get.get("query", "") |
| get.p = get.get("p", 1) |
| get.row = get.get("row", 10) |
| get.classify = get.get("classify", 999) |
| where_parm = [None, (None,)] |
|
|
| if get.type == "all": |
| if get.classify != 999: |
| where_parm = ["classify=?", (get.classify,)] |
| if get.query == "": |
| sites_result = dp.sql("docker_sites").where(where_parm[0], where_parm[1]).order("addtime desc").select() |
| else: |
| where_parm[0] = "classify=? and (name like ? or remark like ?)" |
| where_parm[1] = (get.classify, "%{}%".format(get.query), "%{}%".format(get.query)) |
| sites_result = dp.sql("docker_sites").where(where_parm[0], where_parm[1]).order("addtime desc").select() |
| else: |
| if get.query == "": |
| sites_result = dp.sql("docker_sites").order("addtime desc").select() |
| else: |
| where_parm[0] = "name like ? or remark like ?" |
| where_parm[1] = ("%{}%".format(get.query), "%{}%".format(get.query)) |
| sites_result = dp.sql("docker_sites").where(where_parm[0], where_parm[1]).order("addtime desc").select() |
| else: |
| where_parm[0] = "type=?" |
| where_parm[1] = (get.type,) |
| if get.classify != 999: |
| where_parm[0] = "type=? and classify=?" |
| where_parm[1] = (get.type, get.classify) |
| if get.query == "": |
| sites_result = dp.sql("docker_sites").where(where_parm[0], where_parm[1]).order("addtime desc").select() |
| else: |
| where_parm[0] = "type=? and classify=? and (? in name or ? in remark)" |
| where_parm[1] = (get.type, get.classify, get.query, get.query) |
| sites_result = dp.sql("docker_sites").where(where_parm[0], where_parm[1]).order("addtime desc").select() |
|
|
| sites_result = self.get_page(sites_result, get) |
|
|
| try: |
| path = '/www/server/btwaf/site.json' |
| waf_res = json.loads(public.readFile(path)) |
| except: |
| waf_res = {} |
|
|
| type_infp = { |
| "php": "PHP", |
| "java": "JAVA", |
| "go": "Go", |
| "python": "Python", |
| "proxy": "反向代理", |
| "app": "Docker应用", |
| "nodejs": "Nodejs" |
| } |
|
|
| for site in sites_result["data"]: |
| site["type"] = type_infp[site["type"]] |
| get.site_name = site["name"] |
| project_config = self.read_json_conf(get) |
| site["healthy"] = 1 |
| site["waf"] = {} |
| if not project_config: |
| site["healthy"] = 0 |
| site["conf_path"] = "" |
| site["ssl"] = -1 |
| site["proxy_pass"] = "" |
| continue |
|
|
| site["conf_path"] = public.get_setup_path() + '/panel/vhost/nginx/' + get.site_name + '.conf' |
| site["ssl"] = self.get_site_ssl_info(get.site_name) |
| site["proxy_pass"] = project_config["proxy_info"][0]["proxy_pass"] if len(project_config["proxy_info"]) > 0 else "" |
|
|
| if waf_res: |
| for waf in waf_res: |
| if "open" in waf_res[waf]: |
| site["waf"] = {"status": True} |
|
|
| return self.pageResult(data=sites_result["data"], page=sites_result["page"]) |
|
|
| |
| def create_site(self, get): |
| ''' |
| @name 创建指定类型的网站项目 |
| ''' |
| get.domains = get.get("domains", "") |
| if not get.domains: |
| return public.returnResult(status=False, msg="域名不能为空,至少输入一个域名!") |
| get.remark = get.get("remark", "") |
|
|
| get.domain_list = get.domains.split("\n") if get.domains != "" else [] |
| |
| get.site_port = get.domain_list[0].strip().split(":")[1] if ":" in get.domain_list[0] else "80" |
| get.port_list = [get.site_port] |
| from mod.base.web_conf import util |
| get.domain_name = get.site_name = util.to_puny_code(get.domain_list[0].strip().split(":")[0]).strip().lower() |
| public.check_domain_cloud(get.site_name) |
| if get.domain_name.find("*.") != -1: return public.returnResult(False, "主域名不能是通配符域名!") |
|
|
| cwsres = self.check_web_status() |
| if not cwsres["status"]: return cwsres |
|
|
| from firewallModel.comModel import main as comModel |
| firewall_com = comModel() |
|
|
| get.type = get.get("type", None) |
| if get.type is None: return public.returnResult(False, "type参数不能为空!") |
| get.name = get.get("name", None) |
| if get.name is None: return public.returnResult(False, "name参数不能为空!") |
|
|
| get.proxy_path = get.get("proxy_path", "/") |
| get.runtime_port = None |
| get.enable_php_conf = "" |
| get.port = get.get("port", None) |
| get.runtime_port = get.port |
| get.project_name = None |
| get.project_path = None |
| get.container_id = get.get("container_id", None) |
| if get.port is None: return public.returnResult(False, "port参数不能为空!") |
|
|
| if get.type == "php": |
|
|
| |
| import psutil |
| all_ports = [] |
| for net_port in psutil.net_connections("tcp4"): |
| all_ports.append(net_port.laddr.port) |
|
|
| if int(get.runtime_port) in all_ports: |
| get.port = str(get.runtime_port) |
| from safeModel.firewallModel import main as firewall_main |
| res_dict = firewall_main().get_listening_processes(get) |
| return public.returnResult(False, msg="{}端口已被【{}】占用,请更换端口!".format(get.port, res_dict.get("process_name"))) |
|
|
| run_result = self.run_php(get) |
| if not run_result["status"]: return run_result |
|
|
| |
| enable_php_body = public.readFile("/www/dk_project/runtime/templates/php/enable_php_template.conf") |
| if enable_php_body: self.enable_php_template = enable_php_body |
| get.enable_php_conf = self.enable_php_template.format(port=get.runtime_port) |
|
|
| elif get.type in ("java", "go", "python", "app", "proxy","nodejs"): |
|
|
| get.proxy_pass = get.get("proxy_pass", "http://127.0.0.1:{}".format(get.port)) |
| get.proxy_host = get.get("proxy_host", "$http_host") |
| get.proxy_type = "http" |
| else: |
| return public.returnResult(False, "type参数: {} 不支持!".format(get.type)) |
|
|
| if get.site_port != "80": |
| get.domain_name = "{}_{}".format(get.domain_name, get.site_port) |
| get.site_path = get.get("site_path", "/www/dk_project/wwwroot/{}".format(get.domain_name)) |
| cache_name = "{}_{}".format(get.site_name.replace(".", "_"), get.site_port) |
| else: |
| get.site_path = get.get("site_path", "/www/dk_project/wwwroot/{}".format(get.site_name)) |
| cache_name = get.site_name.replace(".", "_") |
|
|
| if dp.sql("docker_sites").where("name=?", (get.domain_name,)).count(): |
| return public.returnResult(False, "域名【{}】已存在,请勿重复添加!".format(get.domain_name)) |
|
|
| for domain in get.domain_list: |
| domain = domain.strip().split(":")[0] |
| if not public.is_domain(domain): |
| return public.returnResult(False, "域名【{}】格式不正确".format(domain)) |
|
|
| newpid = public.M('domain').where("name=? and port=?", (domain, 80)).getField('pid') |
| if newpid: |
| result = public.M('sites').where("id=?", (newpid,)).find() |
| if result: |
| return public.returnResult(False, '项目类型【{}】已存在域名:{},请勿重复添加!'.format( |
| result['project_type'], domain)) |
|
|
| newpid = dp.sql("docker_domain").where("name=? and port=?", (domain, 80)).getField('pid') |
| if newpid: |
| result = dp.sql("docker_sites").where("id=?", (newpid,)).find() |
| if result: |
| return public.returnResult(False, 'docker网站项目【{}】已存在域名:{},请勿重复添加!'.format(result['name'], domain)) |
|
|
| if not ":" in domain.strip(): continue |
|
|
| d_port = domain.strip().split(":")[1] |
| if not public.checkPort(d_port): |
| return public.returnResult(status=False, msg='端口【{}】不合法!'.format(d_port)) |
|
|
| get.port = d_port |
| firewall_com.set_port_rule(get) |
|
|
| self.site_config_path = os.path.join(self.sites_config_path, get.domain_name) |
| |
| get.http_block = "proxy_cache_path {site_config_path}/proxy_cache_dir levels=1:2 keys_zone={cache_name}_cache:20m inactive=1d max_size=5g;".format( |
| site_config_path=self.site_config_path, |
| cache_name=cache_name |
| ) |
|
|
| get.service_info = { |
| "name": get.name, |
| "port": get.runtime_port, |
| "project_name": get.project_name, |
| "project_path": get.project_path, |
| } |
| get.old_info = {} |
|
|
| get.remark = public.xssencode2(get.get("remark", "")) |
| if get.remark == "": |
| get.remark = get.domain_name |
|
|
| |
| ires = self.insert_sites(get) |
| if not ires["status"]: return ires |
|
|
| |
| self.write_nginx_conf(get) |
|
|
| |
| self.create_must_dir(get) |
| self.create_default_html(get) |
|
|
| self.site_conf_file = '{}/{}.json'.format(self.site_config_path, get.domain_name) |
| public.writeFile(self.site_conf_file, json.dumps(self.init_site_json)) |
|
|
| cres = self.check_after_create(get) |
| if not cres["status"]: return cres |
|
|
| |
| get.id = get.pid |
| get.status = 1 |
| self.SetDirUserINI(get) |
|
|
| public.WriteLog('TYPE_SITE', 'SITE_ADD_SUCCESS', (get.site_name,)) |
| public.set_module_logs('docker_site', 'create', 1) |
| public.set_module_logs('docker_site_{}'.format(get.type), 'create', 1) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="创建网站成功") |
|
|
| |
| def set_remak(self, get): |
| ''' |
| @name 设置指定网站的备注 |
| ''' |
| get.remark = get.get("remark", "") |
| get.id = get.get("id", None) |
| if get.id is None: return public.returnResult(False, "id参数不能为空!") |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| dp.sql("docker_sites").where("id=?", (get.id,)).setField("remark", public.xssencode2(get.remark)) |
|
|
| get.proxy_json_conf["remark"] = public.xssencode2(get.remark) |
| self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( |
| path=self.sites_config_path, |
| site_name=get.site_name |
| ) |
| public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) |
|
|
| return public.returnResult(msg="修改备注成功") |
|
|
| |
| def set_site_edate(self, get): |
| ''' |
| @name 设置网站到期时间 |
| ''' |
| get.edate = get.get("edate", "0000-00-00") |
| get.id = get.get("id", None) |
| if get.id is None: return public.returnResult(False, "id参数不能为空!") |
|
|
| dp.sql("docker_sites").where("id=?", (get.id,)).setField("edate", get.edate) |
| return public.returnResult(msg="设置到期时间成功") |
|
|
| |
| def set_site_status(self, get): |
| ''' |
| @name 设置网站运行状态 |
| ''' |
| get.status = get.get("status", 1) |
| get.id = get.get("id", None) |
| if get.id is None: return public.returnResult(False, "id参数不能为空!") |
| get.site_name = get.get("site_name", None) |
| if get.site_name is None: return public.returnResult(False, "site_name参数不能为空!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| old_file = "{path}/{site_name}/{site_name}.json".format( |
| path="/www/server/proxy_project/sites", |
| site_name=get.site_name |
| ) |
| if not os.path.exists(old_file): |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| os.makedirs("{}/{}".format(self.sites_config_path, get.site_name), exist_ok=True) |
| public.ExecShell("\cp -r {} {}".format(old_file, os.path.join(self.sites_config_path, get.site_name))) |
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| get.proxy_json_conf["stop_site_conf"] = '''rewrite ^/(?!bt-stop\.html$).* /bt-stop.html last; |
| location = /bt-stop.html { # 网站停止,并设置网站停止页面 |
| root /www/server/stop; |
| }''' |
| if int(get.status) == 1: |
| get.proxy_json_conf["stop_site"] = False |
| args = public.dict_obj() |
| args.id = [get.id] |
| args.classify = get.proxy_json_conf["classify"] if "classify" in get.proxy_json_conf else 0 |
| self.set_site_type(args) |
| else: |
| path = '/www/server/stop' |
| if not os.path.exists(path) or not os.path.isfile(path + '/index.html'): |
| os.makedirs(path) |
| public.downloadFile('http://{}/stop.html'.format(public.get_url()), path + '/index.html') |
|
|
| bt_stop = path + '/bt-stop.html' |
| if not os.path.exists(bt_stop): |
| os.symlink(path + '/index.html', bt_stop) |
| if not os.path.islink(bt_stop): |
| os.unlink(bt_stop) |
| os.symlink(path + '/index.html', bt_stop) |
|
|
| get.proxy_json_conf["stop_site"] = True |
| args = public.dict_obj() |
| args.id = [get.id] |
| args.classify = "-2" |
| self.set_site_type(args) |
|
|
| dp.sql("docker_sites").where("id=?", (get.id,)).setField("status", get.status) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置运行状态成功") |
|
|
| |
| def delete_site(self, get): |
| ''' |
| @name 删除指定网站 |
| ''' |
| get.id = get.get("id", None) |
| if get.id is None: return public.returnResult(False, "id参数不能为空!") |
| get.remove_path = get.get("remove_path", 0) |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
| get.reload = get.get("reload/d", 1) |
|
|
| find_result = dp.sql("docker_sites").where("id=?", (get.id,)).find() |
| if not find_result: return public.returnResult(False, "未找到指定网站!") |
|
|
| |
| if find_result["type"] == "php": |
| service_info = json.loads(find_result["service_info"]) |
| public.ExecShell("docker-compose -f {} down".format(os.path.join(service_info["project_path"], "docker-compose.yml"))) |
| public.ExecShell("docker-compose -f {} rm -f".format(os.path.join(service_info["project_path"], "docker-compose.yml"))) |
| public.ExecShell("rm -rf {}".format(service_info["project_path"])) |
|
|
| |
| self.site_config_path = os.path.join(self.sites_config_path, find_result["name"]) |
| public.ExecShell("rm -rf {}".format(self.site_config_path)) |
| nginx_conf = os.path.join("/www/server/panel/vhost/nginx", "{}.conf".format(find_result["name"])) |
| public.ExecShell("rm -rf {}".format(nginx_conf)) |
| redirect_dir = public.get_setup_path() + '/panel/vhost/nginx/redirect/' + get.site_name |
| if os.path.exists(redirect_dir): |
| public.ExecShell('rm -rf {}'.format(redirect_dir)) |
|
|
| logs_file = public.get_logs_path() + '/{}*'.format(get.site_name) |
| public.ExecShell('rm -f {}'.format(logs_file)) |
|
|
| self._site_proxy_conf_path = "{path}/{site_name}".format( |
| path=self.sites_config_path, |
| site_name=get.site_name |
| ) |
| public.ExecShell('rm -rf {}'.format(self._site_proxy_conf_path)) |
|
|
| if get.remove_path == 1: |
| public.ExecShell("rm -rf {}".format(find_result["path"])) |
|
|
| |
| dp.sql("docker_sites").where("id=?", (get.id,)).delete() |
| |
| dp.sql("docker_domain").where("pid=?", (get.id,)).delete() |
|
|
| |
| conf_path = "{path}/{site_name}/{site_name}.json".format( |
| path=self.sites_config_path, |
| site_name=find_result["name"] |
| ) |
| public.ExecShell("rm -rf {}".format(conf_path)) |
|
|
|
|
| if get.reload == 1: |
| public.serviceReload() |
|
|
| return public.returnResult(msg="删除网站成功") |
|
|
| |
| def batch_delete_site(self, get): |
| ''' |
| @name 批量删除指定网站 |
| ''' |
| get.site_list = get.get("site_list", []) |
| get.remove_path = get.get("remove_path/d", 0) |
| get.reload = get.get("reload/d", 0) |
|
|
| try: |
| site_list = json.loads(get.site_list) |
| except: |
| return public.returnResult(False, "请传入需要删除的网站列表!") |
|
|
| acc_list = [] |
| for site in site_list: |
| args = public.dict_obj() |
| args.site_name = site["site_name"] |
| args.remove_path = get.remove_path |
| args.reload = get.reload |
| args.id = site["id"] |
| de_result = self.delete_site(args) |
| if not de_result["status"]: |
| acc_list.append({"site_name": site["site_name"], "status": False}) |
| continue |
|
|
| acc_list.append({"site_name": site["site_name"], "status": True}) |
|
|
| public.serviceReload() |
|
|
| return public.returnResult(True, msg="批量删除站点成功!", data=acc_list) |
|
|
| |
| def prune_sites(self, get): |
| ''' |
| @name 清空所有网站 |
| ''' |
| get.remove_path = get.get("remove_path/d", 0) |
|
|
| select_result = dp.sql("docker_sites").select() |
| acc_list = [] |
| for site in select_result: |
| args = public.dict_obj() |
| args.site_name = site["name"] |
| args.remove_path = get.remove_path |
| args.reload = 0 |
| args.id = site["id"] |
| de_result = self.delete_site(args) |
| if not de_result["status"]: |
| acc_list.append({"site_name": site["name"], "status": False}) |
| continue |
|
|
| acc_list.append({"site_name": site["name"], "status": True}) |
|
|
| public.serviceReload() |
|
|
| return public.returnResult(True, msg="清空所有网站成功!", data=acc_list) |
|
|
| |
| def get_site_path(self, get): |
| ''' |
| @name 获取指定网站的网站目录 |
| ''' |
| get.id = get.get("id", None) |
| if get.id is None: return public.returnResult(False, "id参数不能为空!") |
|
|
| site_result = dp.sql("docker_sites").where("id=?", (get.id,)).find() |
| if not site_result: return public.returnResult(False, "未找到指定网站!") |
|
|
| return public.returnResult(data=site_result) |
|
|
| |
| def set_site_path(self, get): |
| ''' |
| @name 设置指定网站的网站目录 |
| ''' |
| get.id = get.get("id", None) |
| if get.id is None: return public.returnResult(False, "id参数不能为空!") |
| path = get.get("path", None) |
| if path is None: return public.returnResult(False, "path参数不能为空!") |
| get.site_name = get.get("site_name", None) |
| if get.site_name is None: return public.returnResult(False, "site_name参数不能为空!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| get.proxy_json_conf["site_path"] = path |
| dp.sql("docker_sites").where("id=?", (get.id,)).setField("path", path) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
|
|
| |
| if "type" in get.proxy_json_conf and get.proxy_json_conf["type"] == "php": |
| service_info = json.loads(dp.sql("docker_sites").where("id=?", (get.id,)).getField("service_info")) |
| public.ExecShell("sed -i 's,^SITE_PATH=.*,SITE_PATH={},' {}/.env".format(path, service_info["project_path"])) |
| public.ExecShell("docker-compose -f {} up -d".format(os.path.join(service_info["project_path"], "docker-compose.yml"))) |
|
|
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置网站目录成功") |
|
|
| |
| def set_site_run_path(self, get): |
| ''' |
| @name 设置指定网站的运行目录 |
| ''' |
| get.id = get.get("id", None) |
| if get.id is None: return public.returnResult(False, "id参数不能为空!") |
| get.run_path = get.get("run_path", None) |
| if get.run_path is None: return public.returnResult(False, "run_path参数不能为空!") |
| get.site_name = get.get("site_name", None) |
| if get.site_name is None: return public.returnResult(False, "site_name参数不能为空!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| get.proxy_json_conf["run_path"] = get.run_path.replace(get.proxy_json_conf["site_path"], "") |
| if not get.proxy_json_conf["run_path"]: get.proxy_json_conf["run_path"] = "/" |
| dp.sql("docker_sites").where("id=?", (get.id,)).setField("run_path", get.proxy_json_conf["run_path"]) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
|
|
| |
| if "type" in get.proxy_json_conf and get.proxy_json_conf["type"] == "php": |
| service_info = json.loads(dp.sql("docker_sites").where("id=?", (get.id,)).getField("service_info")) |
| public.ExecShell("sed -i 's,^SITE_PATH=.*,SITE_PATH={},' {}/.env".format(os.path.join(get.proxy_json_conf["site_path"], get.proxy_json_conf["run_path"].replace("/","",1)), service_info["project_path"])) |
| public.ExecShell("docker-compose -f {} up -d".format(os.path.join(service_info["project_path"], "docker-compose.yml"))) |
|
|
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置网站运行目录成功") |
|
|
| |
| def set_cert(self, get): |
| ''' |
| @name |
| @author wzz <2024/4/21 下午10:46> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.oid = get.get("oid", "") |
| if get.oid == "": |
| return public.returnResult(status=False, msg="oid不能为空!") |
|
|
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.siteName = get.site_name |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| from mod.project.docker.sites.sslManage import SslManage |
| ssl_manage = SslManage() |
| set_result = ssl_manage.set_cert(get) |
| if not set_result["status"]: return set_result |
|
|
| get.proxy_json_conf["ssl_info"]["ssl_status"] = True |
| get.proxy_json_conf["https_port"] = "443" |
|
|
| self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( |
| path=self.sites_config_path, |
| site_name=get.site_name |
| ) |
| public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) |
|
|
| return set_result |
|
|
| |
| def set_ssl(self, get): |
| ''' |
| @name 保存并启用指定网站的SSL |
| ''' |
| get.key = get.get("key", "") |
| if get.key == "": |
| return public.returnResult(status=False, msg="key不能为空!") |
|
|
| get.csr = get.get("csr", "") |
| if get.csr == "": |
| return public.returnResult(status=False, msg="csr不能为空!") |
|
|
| get.siteName = get.get("siteName", "") |
| get.site_name = get.get("site_name", "") |
| if get.siteName == "": |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="网站名不能为空!") |
|
|
| get.siteName = get.site_name |
| else: |
| get.site_name = get.siteName |
|
|
| get.type = -1 |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| from mod.project.docker.sites.sslManage import SslManage |
| ssl_manage = SslManage() |
| result = ssl_manage.set_ssl_to_site(get) |
| if not result["status"]: return result |
|
|
| get.proxy_json_conf["ssl_info"]["ssl_status"] = True |
| get.proxy_json_conf["https_port"] = "443" |
|
|
| self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( |
| path=self.sites_config_path, |
| site_name=get.site_name |
| ) |
| public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) |
|
|
| return result |
|
|
| |
| def apply_cert_api(self, get): |
| ''' |
| @name |
| @author wzz <2024/4/21 下午11:34> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.domains = get.get("domains", "") |
| if get.domains == "": |
| return public.returnResult(status=False, msg="domains不能为空!") |
|
|
| get.auth_type = get.get("auth_type", "") |
| if get.auth_type == "": |
| return public.returnResult(status=False, msg="auth_type不能为空!") |
|
|
| get.auth_to = get.get("auth_to", "") |
| if get.auth_to == "": |
| return public.returnResult(status=False, msg="auth_to不能为空!") |
|
|
| get.auto_wildcard = get.get("auto_wildcard", "") |
| if get.auto_wildcard == "": |
| return public.returnResult(status=False, msg="auto_wildcard不能为空!") |
|
|
| get.id = get.get("id", "") |
| if get.id == "": |
| return public.returnResult(status=False, msg="id不能为空!") |
|
|
| get.siteName = get.site_name |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| from mod.project.docker.sites.sslManage import Acme_V2 |
| acme = Acme_V2() |
| result = acme.apply_cert_api(get) |
| if not result["status"]: return result |
|
|
| get.proxy_json_conf["ssl_info"]["ssl_status"] = True |
| get.proxy_json_conf["https_port"] = "443" |
|
|
| self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( |
| path=self.sites_config_path, |
| site_name=get.site_name |
| ) |
| public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) |
|
|
| return result |
|
|
| |
| def apply_dns_auth(self, get): |
| ''' |
| @name |
| @author wzz <2024/4/21 下午11:36> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.index = get.get("index", "") |
| if get.index == "": |
| return public.returnResult(status=False, msg="index不能为空!") |
|
|
| from acme_v2 import acme_v2 |
| acme = acme_v2() |
| return acme.apply_dns_auth(get) |
|
|
| |
| def SetBatchCertToSite(self, get): |
| ''' |
| @name |
| @author wzz <2024/4/21 下午11:44> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.BatchInfo = get.get("BatchInfo", "") |
| if get.BatchInfo == "": |
| return public.returnResult(status=False, msg="BatchInfo不能为空!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| from mod.project.docker.sites.sslManage import SslManage |
| ssl_manage = SslManage() |
| set_result = ssl_manage.SetBatchCertToSite(get) |
| if not "successList" in set_result: return set_result |
|
|
| for re in set_result["successList"]: |
| if re["status"] and re["siteName"] == get.site_name: |
| get.proxy_json_conf["ssl_info"]["ssl_status"] = True |
| break |
|
|
| self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( |
| path=self.sites_config_path, |
| site_name=get.site_name |
| ) |
| public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) |
|
|
| return set_result |
|
|
| |
| def set_force_https(self, get): |
| ''' |
| @name 设置强制https |
| @param get: |
| site_name: 网站名 |
| force_https: 1/0 |
| @return: |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.force_https = get.get("force_https/d", 999) |
| if get.force_https == 999: |
| return public.returnResult(status=False, msg="force_https不能为空!") |
|
|
| get.siteName = get.site_name |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| get.proxy_json_conf["ssl_info"]["force_https"] = True if get.force_https == 1 else False |
|
|
| from mod.project.docker.sites.sslManage import SslManage |
| ssl_manage = SslManage() |
| if get.force_https == 1: |
| result = ssl_manage.HttpToHttps(get) |
| else: |
| result = ssl_manage.CloseToHttps(get) |
|
|
| if not result["status"]: return result |
|
|
| self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( |
| path=self.sites_config_path, |
| site_name=get.site_name |
| ) |
| public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) |
|
|
| return result |
|
|
| |
| def close_ssl(self, get): |
| ''' |
| @name |
| @author wzz <2024/4/21 下午11:04> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.siteName = get.get("siteName", "") |
| if get.siteName == "": |
| return public.returnResult(status=False, msg="siteName不能为空!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| from mod.project.docker.sites.sslManage import SslManage |
| ssl_manage = SslManage() |
| result = ssl_manage.CloseSSLConf(get) |
| if not result["status"]: return result |
|
|
| get.proxy_json_conf["ssl_info"]["ssl_status"] = False |
| get.proxy_json_conf["https_port"] = "443" |
|
|
| self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( |
| path=self.sites_config_path, |
| site_name=get.site_name |
| ) |
| public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) |
|
|
| return result |
|
|
| |
| def add_domain(self, get): |
| ''' |
| @name |
| @author wzz <2024/4/19 下午11:46> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
| get.id = get.get("id", "") |
| if get.id == "": |
| return public.returnResult(status=False, msg="id不能为空!") |
| get.domains = get.get("domains", "") |
| if get.domains == "": |
| return public.returnResult(status=False, msg="domains不能为空!") |
| if "," in get.domains: |
| return public.returnResult(status=False, msg="域名不能包含逗号!") |
|
|
| isError = public.checkWebConfig() |
| if isError != True: |
| return public.returnResult(False, 'ERROR: 检测到配置文件有错误,请先排除后再操作<br><br><a style="color:red;">' + isError.replace("\n", '<br>') + '</a>') |
|
|
| get.domain_list = get.domains.strip().replace(' ', '').split("\n") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| from firewallModel.comModel import main as comModel |
| firewall_com = comModel() |
|
|
| res_domains = [] |
| for domain in get.domain_list: |
| if domain == "": continue |
| domain = domain.strip().split(':') |
| get.domain = self.ToPunycode(domain[0]).lower() |
| get.port = '80' |
|
|
| |
| if get.domain.find('*') != -1 and get.domain.find('*.') == -1: |
| res_domains.append({"name": get.domain, "status": False, "msg": '域名格式不正确'}) |
| continue |
|
|
| |
| reg = "^([\w\-\*]{1,100}\.){1,24}([\w\-]{1,24}|[\w\-]{1,24}\.[\w\-]{1,24})$" |
| if not re.match(reg, get.domain): |
| res_domains.append({"name": get.domain, "status": False, "msg": '域名格式不正确'}) |
| continue |
|
|
| |
| if len(domain) == 2: |
| get.port = domain[1] |
| if get.port == "": get.port = "80" |
|
|
| |
| if not re.match("^\d+$", get.port): |
| res_domains.append({"name": get.domain, "status": False, "msg": '端口不合法,应该为数字'}) |
| continue |
|
|
| not_used_ports = ('21', '25', '443', '888', '8888', '8443') |
| if get.port in not_used_ports: |
| res_domains.append( |
| {"name": get.domain, "status": False, "msg": '端口不合法,请勿使用常用端口,例如:ssh的22端口等'}) |
| continue |
|
|
| intport = int(get.port) |
| if intport < 1 or intport > 65535: |
| res_domains.append({"name": get.domain, "status": False, "msg": '端口范围不合法'}) |
| continue |
|
|
| |
| find_pid = dp.sql("docker_domain").where("name=? and port=?", (get.domain, get.port)).getField('pid') |
| if find_pid: |
| siteName = dp.sql("docker_sites").where("id=?", (find_pid,)).getField('name') |
| if siteName: |
| res_domains.append({"name": get.domain, "status": False, "msg": '指定域名[{}]已被网站[{}]绑定过了'.format(get.domain, siteName)}) |
| continue |
|
|
| dp.sql("docker_domain").where("pid=?", (find_pid,)).delete() |
|
|
| |
| |
| |
|
|
| |
| if not get.domain in get.proxy_json_conf["domain_list"]: |
| get.proxy_json_conf["domain_list"].append(get.domain) |
| if not get.port in get.proxy_json_conf["site_port"]: |
| get.proxy_json_conf["site_port"].append(get.port) |
|
|
| |
| dp.sql("docker_domain").add('name,port,pid', (get.domain, get.port, get.id)) |
|
|
| firewall_com.set_port_rule(get) |
| res_domains.append({"name": get.domain, "status": True}) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(status=True, data=res_domains) |
|
|
| |
| def del_domain(self, get): |
| ''' |
| @name |
| @author wzz <2024/4/20 上午12:07> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.id = get.get("id", "") |
| if get.id == "": |
| return public.returnResult(status=False, msg="id不能为空!") |
| get.port = get.get("port", "") |
| if get.port == "": |
| return public.returnResult(status=False, msg="port不能为空!") |
| get.domain = get.get("domain", "") |
| if get.domain == "": |
| return public.returnResult(status=False, msg="domain不能为空!") |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
| get.reload = get.get("reload/d", 1) |
|
|
| |
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| if len(get.proxy_json_conf["domain_list"]) < 2 and dp.sql("docker_domain").where("pid=?", (get.id,)).count() < 2: |
| return public.returnResult(status=False, msg="至少保留一个域名!") |
|
|
| while get.domain in get.proxy_json_conf["domain_list"]: |
| get.proxy_json_conf["domain_list"].remove(get.domain) |
| if get.port in get.proxy_json_conf["site_port"] and len(get.proxy_json_conf["site_port"]) != 1: |
| find_r = dp.sql("docker_domain").where("name=? and port=?", (get.domain, get.port)).find() |
| if find_r: |
| while get.port in get.proxy_json_conf["site_port"]: |
| get.proxy_json_conf["site_port"].remove(get.port) |
|
|
| dp.sql("docker_domain").where("name=? and port=?", (get.domain, get.port)).delete() |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| if get.reload == 1: |
| public.serviceReload() |
|
|
| return public.returnResult(status=True, msg="删除域名成功") |
|
|
| |
|
|
| def batch_del_domain(self, get): |
| ''' |
| @name 批量删除指定网站域名 |
| @param get: |
| @return: |
| ''' |
| get.del_domain_list = get.get("del_domain_list", None) |
| if get.del_domain_list is None: |
| return public.returnResult(status=False, msg="del_domain_list不能为空!") |
|
|
| try: |
| get.del_domain_list = json.loads(get.del_domain_list) |
| except: |
| return public.returnResult(status=False, msg="del_domain_list格式错误!") |
|
|
| res_domains = {"success": [], "error": []} |
| for domain in get.del_domain_list: |
| args = public.dict_obj() |
| args.id = domain["id"] |
| args.port = domain["port"] |
| args.domain = domain["domain"] |
| args.site_name = domain["site_name"] |
| args.reload = 0 |
| del_result = self.del_domain(args) |
| if not del_result["status"]: |
| res_domains["error"].append({"domain": args.domain, "msg": del_result["msg"]}) |
| continue |
|
|
| res_domains["success"].append({"domain": args.domain}) |
| public.serviceReload() |
|
|
| return public.returnResult(status=True, data=res_domains) |
|
|
| |
| def set_global_log(self, get): |
| ''' |
| @name |
| @author wzz <2024/4/18 下午9:58> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.log_type = get.get("log_type", "default") |
| if not get.log_type in ["default", "file", "rsyslog", "off"]: |
| return public.returnResult(status=False, msg="日志类型错误,请传入default/file/rsyslog/off!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| get.proxy_json_conf["proxy_log"]["log_type"] = get.log_type |
|
|
| if get.log_type == "file": |
| get.log_path = get.get("log_path", "") |
| if get.log_path == "": |
| return public.returnResult(status=False, msg="日志路径不能为空!") |
| if not get.log_path.startswith("/"): |
| return public.returnResult(status=False, msg="日志路径必须以/开头!") |
|
|
| get.proxy_json_conf["proxy_log"]["log_path"] = get.log_path |
| get.proxy_json_conf["proxy_log"]["log_conf"] = self.init_site_json["proxy_log"]["log_conf"].format( |
| log_path=get.log_path, |
| site_name=get.site_name |
| ) |
| elif get.log_type == "rsyslog": |
| get.log_path = get.get("log_path", "") |
| if get.log_path == "": |
| return public.returnResult(status=False, msg="日志路径不能为空!") |
| site_name = get.site_name.replace(".", "_") |
| get.proxy_json_conf["proxy_log"]["log_conf"] = ( |
| "\n access_log syslog:server={server_host},nohostname,tag=nginx_{site_name}_access;" |
| "\n error_log syslog:server={server_host},nohostname,tag=nginx_{site_name}_error;" |
| .format( |
| server_host=get.log_path, |
| site_name=site_name |
| )) |
| get.proxy_json_conf["proxy_log"]["rsyslog_host"] = get.log_path |
| elif get.log_type == "off": |
| get.proxy_json_conf["proxy_log"]["log_conf"] = "\n access_log off;\n error_log /dev/null;" |
| else: |
| get.proxy_json_conf["proxy_log"]["log_conf"] = " " + self.init_site_json["proxy_log"][ |
| "log_conf"].format( |
| log_path=public.get_logs_path(), |
| site_name=get.site_name |
| ) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def set_dir_auth(self, get): |
| ''' |
| @name 设置basic_auth |
| @param auth_type: add/edit |
| auth_path: /api |
| username: admin |
| password: admin |
| @return: |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.name = get.get("name", "") |
| if get.name == "": |
| return public.returnResult(status=False, msg="name不能为空!") |
|
|
| get.auth_path = get.get("auth_path", "") |
| if get.auth_path == "": |
| return public.returnResult(status=False, msg="auth_path不能为空!") |
| if not get.auth_path.startswith("/"): |
| return public.returnResult(status=False, msg="auth_path必须以/开头!") |
|
|
| get.username = get.get("username", "") |
| get.password = get.get("password", "") |
| if get.username == "" or get.password == "": |
| return public.returnResult(status=False, msg="用户名和密码不能为空!") |
|
|
| if len(get.password) > 8: |
| return public.returnResult(status=False, msg="密码不能超过8位,超过的部分无法验证!") |
|
|
| get.password = public.hasPwd(get.password) |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| if len(get.proxy_json_conf["basic_auth"]) == 0: |
| return public.returnResult(status=False, msg="【{}】不存在http认证中,请先添加!".format(get.auth_path)) |
|
|
| for i in range(len(get.proxy_json_conf["basic_auth"])): |
| if get.proxy_json_conf["basic_auth"][i]["auth_path"] == get.auth_path: |
| if get.proxy_json_conf["basic_auth"][i]["auth_name"] == get.name: |
| get.proxy_json_conf["basic_auth"][i]["username"] = get.username |
| get.proxy_json_conf["basic_auth"][i]["password"] = get.password |
| break |
|
|
| auth_file = "/www/server/pass/{site_name}/{name}.htpasswd".format(site_name=get.site_name, name=get.name) |
| public.writeFile(auth_file, "{}:{}".format(get.username, get.password)) |
|
|
| self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( |
| path=self.sites_config_path, |
| site_name=get.site_name |
| ) |
| public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) |
|
|
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def add_dir_auth(self, get): |
| ''' |
| @name 添加指定网站的basic_auth |
| @author wzz <2024/4/22 下午4:17> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.auth_path = get.get("auth_path", "") |
| if get.auth_path == "": |
| return public.returnResult(status=False, msg="auth_path不能为空!") |
| if not get.auth_path.startswith("/"): |
| return public.returnResult(status=False, msg="auth_path必须以/开头!") |
|
|
| get.name = get.get("name", "") |
| if get.name == "": |
| return public.returnResult(status=False, msg="name不能为空!") |
|
|
| get.username = get.get("username", "") |
| if get.username == "": |
| return public.returnResult(status=False, msg="username不能为空!") |
|
|
| get.password = get.get("password", "") |
| if get.password == "": |
| return public.returnResult(status=False, msg="password不能为空!") |
| if len(get.password) > 8: |
| return public.returnResult(status=False, msg="密码不能超过8位,超过的部分无法验证!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| auth_file = "/www/server/pass/{site_name}/{name}.htpasswd".format(site_name=get.site_name, name=get.name) |
|
|
| auth_conf = { |
| "auth_status": True, |
| "auth_path": get.auth_path, |
| "auth_name": get.name, |
| "username": get.username, |
| "password": public.hasPwd(get.password), |
| "auth_file": auth_file, |
| } |
|
|
| if len(get.proxy_json_conf["basic_auth"]) != 0: |
| for i in range(len(get.proxy_json_conf["basic_auth"])): |
| if get.proxy_json_conf["basic_auth"][i]["auth_path"] == get.auth_path: |
| return public.returnResult(status=False, |
| msg="【{}】已存在http认证中,无法重复添加!".format(get.auth_path)) |
|
|
| if not os.path.exists("/www/server/pass"): |
| public.ExecShell("mkdir -p /www/server/pass") |
| if not os.path.exists("/www/server/pass/{}".format(get.site_name)): |
| public.ExecShell("mkdir -p /www/server/pass/{}".format(get.site_name)) |
| public.writeFile(auth_file, "{}:{}".format(get.username, public.hasPwd(get.password))) |
|
|
| get.proxy_json_conf["basic_auth"].append(auth_conf) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
|
|
| return public.returnResult(msg="添加成功!") |
|
|
| |
| def del_dir_auth(self, get): |
| ''' |
| @name 删除指定网站的basic_auth |
| @author wzz <2024/4/23 上午9:35> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.auth_path = get.get("auth_path", "") |
| if get.auth_path == "": |
| return public.returnResult(status=False, msg="auth_path不能为空!") |
|
|
| get.name = get.get("name", "") |
| if get.name == "": |
| return public.returnResult(status=False, msg="name不能为空!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| auth_file = "/www/server/pass/{site_name}/{name}.htpasswd".format(site_name=get.site_name, name=get.name) |
|
|
| panel_port = public.readFile('/www/server/panel/data/port.pl') |
| proxy_list = self.get_proxy_list(get) |
| if proxy_list["data"][0]["proxy_pass"] == "https://127.0.0.1:{}".format( |
| panel_port.strip()) and get.auth_path.strip() == "/": |
| return public.returnResult(False, "【{}】是面板的反代,不能删除【/】的http认证!".format(get.site_name)) |
|
|
| if len(get.proxy_json_conf["basic_auth"]) != 0: |
| for i in range(len(get.proxy_json_conf["basic_auth"])): |
| if get.proxy_json_conf["basic_auth"][i]["auth_path"] == get.auth_path: |
| if get.proxy_json_conf["basic_auth"][i]["auth_name"] == get.name: |
| get.proxy_json_conf["basic_auth"].pop(i) |
| break |
|
|
| public.ExecShell("rm -f {}".format(auth_file)) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="删除成功!") |
|
|
| |
| def set_global_gzip(self, get): |
| ''' |
| @name 设置全局gzip |
| @param get: |
| @return: |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.gzip_status = get.get("gzip_status/d", 999) |
| if get.gzip_status == 999: |
| return public.returnResult(status=False, msg="gzip_status不能为空,请传number 1或0!") |
| get.gzip_min_length = get.get("gzip_min_length", "10k") |
| get.gzip_comp_level = get.get("gzip_comp_level", "6") |
| if get.gzip_min_length[0] == "0" or get.gzip_min_length.startswith("-"): |
| return public.returnResult(status=False, msg="gzip_min_length参数不合法,请输入大于0的数字!") |
| if get.gzip_comp_level == "0" or get.gzip_comp_level.startswith("-"): |
| return public.returnResult(status=False, msg="gzip_comp_level参数不合法,请输入大于0的数字!") |
| get.gzip_types = get.get( |
| "gzip_types", |
| "text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/json image/jpeg image/gif image/png font/ttf font/otf image/svg+xml application/xml+rss text/x-js" |
| ) |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| get.proxy_json_conf["gzip"]["gzip_status"] = True if get.gzip_status == 1 else False |
| if get.proxy_json_conf["gzip"]["gzip_status"]: |
| get.proxy_json_conf["gzip"]["gzip_status"] = True |
| get.proxy_json_conf["gzip"]["gzip_min_length"] = get.gzip_min_length |
| get.proxy_json_conf["gzip"]["gzip_comp_level"] = get.gzip_comp_level |
| get.proxy_json_conf["gzip"]["gzip_types"] = get.gzip_types |
| get.gzip_conf = ("gzip on;" |
| "\n gzip_min_length {gzip_min_length};" |
| "\n gzip_buffers 4 16k;" |
| "\n gzip_http_version 1.1;" |
| "\n gzip_comp_level {gzip_comp_level};" |
| "\n gzip_types {gzip_types};" |
| "\n gzip_vary on;" |
| "\n gzip_proxied expired no-cache no-store private auth;" |
| "\n gzip_disable \"MSIE [1-6]\.\";").format( |
| gzip_min_length=get.gzip_min_length, |
| gzip_comp_level=get.gzip_comp_level, |
| gzip_types=get.gzip_types |
| ) |
| get.proxy_json_conf["gzip"]["gzip_conf"] = get.gzip_conf |
| else: |
| get.proxy_json_conf["gzip"]["gzip_conf"] = "" |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def set_global_cache(self, get): |
| ''' |
| @name 设置全局缓存 |
| @param get: |
| @return: |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.cache_status = get.get("cache_status/d", 999) |
| if get.cache_status == 999: |
| return public.returnResult(status=False, msg="cache_status不能为空,请传number 1或0!") |
|
|
| get.expires = get.get("expires", "1d") |
| if get.expires[0] == "0" or get.expires.startswith("-"): |
| return public.returnResult(status=False, msg="expires参数不合法,请输入大于0的数字!") |
| expires = "expires {}".format(get.expires) |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| static_cache = ("\n location ~ .*\\.(css|js|jpe?g|gif|png|webp|woff|eot|ttf|svg|ico|css\.map|js\.map)$" |
| "\n {{" |
| "\n {expires};" |
| "\n error_log /dev/null;" |
| "\n access_log /dev/null;" |
| "\n }}").format( |
| expires=expires, |
| ) |
|
|
| cache_conf = ("\n proxy_cache {cache_zone};" |
| "\n proxy_cache_key $host$uri$is_args$args;" |
| "\n proxy_ignore_headers Set-Cookie Cache-Control expires X-Accel-Expires;" |
| "\n proxy_cache_valid 200 304 301 302 {expires};" |
| "\n proxy_cache_valid 404 1m;" |
| "{static_cache}").format( |
| cache_zone=get.proxy_json_conf["proxy_cache"]["cache_zone"], |
| expires=get.expires, |
| static_cache=get.proxy_json_conf["proxy_cache"]["static_cache"] if get.proxy_json_conf["proxy_cache"][ |
| "static_cache"] != "" else static_cache |
| ) |
|
|
| get.proxy_json_conf["proxy_cache"]["cache_status"] = True if get.cache_status == 1 else False |
| if get.proxy_json_conf["proxy_cache"]["cache_status"]: |
| get.proxy_json_conf["proxy_cache"]["cache_status"] = True |
| get.proxy_json_conf["proxy_cache"]["expires"] = get.expires |
| get.proxy_json_conf["proxy_cache"]["cache_conf"] = cache_conf |
| else: |
| get.proxy_json_conf["proxy_cache"]["cache_status"] = False |
| get.proxy_json_conf["proxy_cache"]["cache_conf"] = static_cache |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def set_global_websocket(self, get): |
| ''' |
| @name |
| @author wzz <2024/4/19 下午2:37> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.websocket_status = get.get("websocket_status/d", 999) |
| if get.websocket_status == 999: |
| return public.returnResult(status=False, msg="websocket_status不能为空,请传number 1或0!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| if get.websocket_status == 1: |
| get.proxy_json_conf["websocket"]["websocket_status"] = True |
| else: |
| get.proxy_json_conf["websocket"]["websocket_status"] = False |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def CreateRedirect(self, get): |
| ''' |
| @name |
| @author wzz <2024/4/22 上午10:27> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.domainorpath = get.get("domainorpath", "") |
| if get.domainorpath == "": |
| return public.returnResult(status=False, msg="domainorpath不能为空!") |
|
|
| get.redirecttype = get.get("redirecttype", "") |
| if get.redirecttype == "": |
| return public.returnResult(status=False, msg="redirecttype不能为空!") |
|
|
| get.redirectpath = get.get("redirectpath", "") |
| if get.domainorpath == "path" and get.redirectpath == "": |
| return public.returnResult(status=False, msg="redirectpath不能为空!") |
|
|
| get.tourl = get.get("tourl", "") |
| if get.tourl == "": |
| return public.returnResult(status=False, msg="tourl不能为空!") |
|
|
| get.redirectdomain = get.get("redirectdomain", "") |
| if get.domainorpath == "domain" and get.redirectdomain == "": |
| return public.returnResult(status=False, msg="redirectdomain不能为空!") |
|
|
| get.redirectname = get.get("redirectname", "") |
| if get.redirectname == "": |
| return public.returnResult(status=False, msg="redirectname不能为空!") |
|
|
| get.sitename = get.site_name |
| get.type = 1 |
| try: |
| get.holdpath = int(get.get("holdpath", 1)) |
| except: |
| get.holdpath = 1 |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| get.proxy_json_conf["redirect"]["redirect_status"] = True |
|
|
| from panelRedirect import panelRedirect |
| result = panelRedirect().CreateRedirect(get) |
|
|
| self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( |
| path=self.sites_config_path, |
| site_name=get.site_name |
| ) |
| public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) |
|
|
| return result |
|
|
| |
| def DeleteRedirect(self, get): |
| ''' |
| @name 删除指定网站的某个重定向规则 |
| @author wzz <2024/4/22 上午10:45> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.redirectname = get.get("redirectname", "") |
| if get.redirectname == "": |
| return public.returnResult(status=False, msg="redirectname不能为空!") |
|
|
| get.sitename = get.site_name |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| from panelRedirect import panelRedirect |
| redirect_list = panelRedirect().GetRedirectList(get) |
| if len(redirect_list) == 0: |
| get.proxy_json_conf["redirect"]["redirect_status"] = False |
| self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( |
| path=self.sites_config_path, |
| site_name=get.site_name |
| ) |
| public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) |
|
|
| return panelRedirect().DeleteRedirect(get) |
|
|
| |
| def ModifyRedirect(self, get): |
| ''' |
| @name 编辑指定网站的某个重定向规则 |
| @author wzz <2024/4/23 上午10:38> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.domainorpath = get.get("domainorpath", "") |
| if get.domainorpath == "": |
| return public.returnResult(status=False, msg="domainorpath不能为空!") |
|
|
| get.redirecttype = get.get("redirecttype", "") |
| if get.redirecttype == "": |
| return public.returnResult(status=False, msg="redirecttype不能为空!") |
|
|
| get.redirectpath = get.get("redirectpath", "") |
| if get.domainorpath == "path" and get.redirectpath == "": |
| return public.returnResult(status=False, msg="redirectpath不能为空!") |
|
|
| get.tourl = get.get("tourl", "") |
| if get.tourl == "": |
| return public.returnResult(status=False, msg="tourl不能为空!") |
|
|
| get.redirectdomain = get.get("redirectdomain", "") |
| if get.domainorpath == "domain" and get.redirectdomain == "": |
| return public.returnResult(status=False, msg="redirectdomain不能为空!") |
|
|
| get.redirectname = get.get("redirectname", "") |
| if get.redirectname == "": |
| return public.returnResult(status=False, msg="redirectname不能为空!") |
|
|
| get.sitename = get.site_name |
| get.type = get.get("type/d", 1) |
| get.holdpath = get.get("holdpath/d", 1) |
|
|
| from panelRedirect import panelRedirect |
|
|
| return panelRedirect().ModifyRedirect(get) |
|
|
| |
| def GetRedirectFile(self, get): |
| ''' |
| @name 获取指定网站指定重定向规则的信息 |
| @author wzz <2024/4/26 下午3:32> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.path = get.get("path", "") |
| if get.path == "": |
| return public.returnResult(status=False, msg="path不能为空!") |
|
|
| if not os.path.exists(get.path): |
| return public.returnResult(status=False, msg="重定向已停止或配置文件目录不存在!") |
|
|
| import files |
| f = files.files() |
| return f.GetFileBody(get) |
|
|
| |
| def GetSecurity(self, get): |
| ''' |
| @name 获取防盗链信息 |
| ''' |
| file = '/www/server/panel/vhost/nginx/' + get.name + '.conf' |
| conf = public.readFile(file) |
| data = {} |
| if type(conf) == bool: return public.returnMsg(False, '读取配置文件失败!') |
| if conf.find('SECURITY-START') != -1: |
| rep = "#SECURITY-START(\n|.)+#SECURITY-END" |
| tmp = re.search(rep, conf).group() |
| content = re.search("\(.+\)\$", tmp) |
| if content: |
| data['fix'] = content.group().replace('(', '').replace(')$', '').replace('|', ',') |
| else: |
| data['fix'] = '' |
| try: |
| data['domains'] = ','.join(list(set(re.search("valid_referers\s+none\s+blocked\s+(.+);\n", tmp).groups()[0].split()))) |
| except: |
| data['domains'] = ','.join(list(set(re.search("valid_referers\s+(.+);\n", tmp).groups()[0].split()))) |
| data['status'] = True |
| data['http_status'] = tmp.find('none blocked') != -1 |
| try: |
| data['return_rule'] = re.findall(r'(return|rewrite)\s+.*(\d{3}|(/.+)\s+(break|last));', conf)[0][1].replace('break', '').strip() |
| except: |
| data['return_rule'] = '404' |
| else: |
| conf_file = '/www/server/panel/vhost/config/{}_door_chain.json'.format(get.name) |
| try: |
| data = json.loads(public.readFile(conf_file)) |
| data['status'] = data['status'] == "true" |
| except: |
| data = {} |
| data['fix'] = 'jpg,jpeg,gif,png,js,css' |
| domains = public.M('docker_domain').where('pid=?', (get.id,)).field('name').select() |
| tmp = [] |
| for domain in domains: |
| tmp.append(domain['name']) |
| data['domains'] = ','.join(tmp) |
| data['return_rule'] = '404' |
| data['status'] = False |
| data['http_status'] = False |
| return data |
|
|
| |
| def SetSecurity(self, get): |
| ''' |
| @name 设置防盗链 |
| @author wzz <2024/4/22 上午11:12> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.fix = get.get("fix", "") |
| if get.fix == "": |
| return public.returnResult(status=False, msg="fix不能为空!") |
|
|
| get.domains = get.get("domains", "") |
| if get.domains == "": |
| return public.returnResult(status=False, msg="domains不能为空!") |
|
|
| get.return_rule = get.get("return_rule", "") |
| if get.return_rule == "": |
| return public.returnResult(status=False, msg="return_rule不能为空!") |
|
|
| get.http_status = get.get("http_status", "") |
| if get.http_status == "": |
| return public.returnResult(status=False, msg="http_status不能为空!") |
|
|
| get.status = get.get("status", "") |
| if get.status == "": |
| return public.returnResult(status=False, msg="status不能为空!") |
|
|
| get.id = get.get("id", "") |
| if get.id == "": |
| return public.returnResult(status=False, msg="id不能为空!") |
|
|
| get.name = get.site_name |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| get.proxy_json_conf["security"]["security_status"] = True if get.status == "true" else False |
| get.proxy_json_conf["security"]["static_resource"] = get.fix |
| get.proxy_json_conf["security"]["domains"] = get.domains |
| get.proxy_json_conf["security"]["return_resource"] = get.return_rule |
| get.proxy_json_conf["security"]["http_status"] = True if get.http_status else False |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def add_ip_limit(self, get): |
| ''' |
| @name 添加全局IP黑白名单 |
| @author wzz <2024/4/23 下午3:08> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.ip_type = get.get("ip_type", "black") |
| if get.ip_type not in ["black", "white"]: |
| return public.returnResult(status=False, msg="ip_type参数错误,必须传black或white!") |
|
|
| get.ips = get.get("ips", "") |
| if get.ips == "": |
| return public.returnResult(status=False, msg="ips不能为空,请输入IP,一行一个!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| get.ips = get.ips.split("\n") |
| for ip in get.ips: |
| if ip not in get.proxy_json_conf["ip_limit"]["ip_{}".format(get.ip_type)]: |
| get.proxy_json_conf["ip_limit"]["ip_{}".format(get.ip_type)].append(ip) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def del_ip_limit(self, get): |
| ''' |
| @name 删除全局IP黑白名单 |
| @author wzz <2024/4/23 下午3:12> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.ip_type = get.get("ip_type", "black") |
| if get.ip_type not in ["black", "white"]: |
| return public.returnResult(status=False, msg="ip_type参数错误,必须传black或white!") |
|
|
| get.ip = get.get("ip", "") |
| if get.ip == "": |
| return public.returnResult(status=False, msg="ip不能为空,请输入IP!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| if get.ip in get.proxy_json_conf["ip_limit"]["ip_{}".format(get.ip_type)]: |
| get.proxy_json_conf["ip_limit"]["ip_{}".format(get.ip_type)].remove(get.ip) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="删除成功!") |
|
|
| |
| def batch_del_ip_limit(self, get): |
| ''' |
| @name 批量删除全局IP黑白名单 |
| @author wzz <2024/4/23 下午3:14> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.ip_type = get.get("ip_type", "black") |
| if get.ip_type not in ["black", "white", "all"]: |
| return public.returnResult(status=False, msg="ip_type参数错误,必须传black或white!") |
|
|
| get.ips = get.get("ips", "") |
| if get.ips == "": |
| return public.returnResult(status=False, msg="ips不能为空,请输入IP,一行一个!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| get.ips = get.ips.split("\n") |
| for ip in get.ips: |
| if get.ip_type == "all": |
| if ip in get.proxy_json_conf["ip_limit"]["ip_black"]: |
| get.proxy_json_conf["ip_limit"]["ip_black"].remove(ip) |
| if ip in get.proxy_json_conf["ip_limit"]["ip_white"]: |
| get.proxy_json_conf["ip_limit"]["ip_white"].remove(ip) |
| else: |
| if ip in get.proxy_json_conf["ip_limit"]["ip_{}".format(get.ip_type)]: |
| get.proxy_json_conf["ip_limit"]["ip_{}".format(get.ip_type)].remove(ip) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="删除成功!") |
|
|
| |
| def get_proxy_list(self, get): |
| ''' |
| @name |
| @author wzz <2024/4/22 下午9:02> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.proxy_path = get.get("proxy_path", "") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| if len(get.proxy_json_conf["proxy_info"]) == 0: |
| return public.returnResult(status=False, msg="没有代理信息!") |
|
|
| subs_filter = get.proxy_json_conf["subs_filter"] if "subs_filter" in get.proxy_json_conf else \ |
| public.ExecShell("nginx -V 2>&1|grep 'ngx_http_substitutions_filter' -o")[0] != "" |
|
|
| if get.proxy_path != "": |
| for info in get.proxy_json_conf["proxy_info"]: |
| if not "proxy_buffering" in info: info["proxy_buffering"] = True |
| if info["proxy_path"] == get.proxy_path: |
| info["global_websocket"] = get.proxy_json_conf["websocket"]["websocket_status"] |
| info["subs_filter"] = subs_filter |
| if "http://unix:" in info["proxy_pass"]: |
| info["proxy_pass"] = info["proxy_pass"].replace("http://unix:", "") |
| return public.returnResult(data=info) |
| else: |
| return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) |
|
|
| return public.returnResult(data=get.proxy_json_conf["proxy_info"]) |
|
|
| |
| def get_global_conf(self, get): |
| ''' |
| @name 获取指定网站的所有配置信息 |
| @author wzz <2024/4/23 上午11:16> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| return public.returnResult(data=get.proxy_json_conf) |
|
|
| |
| def set_url_proxy(self, get): |
| ''' |
| @name |
| @author wzz <2024/4/22 下午9:04> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.proxy_path = get.get("proxy_path", "") |
| if get.proxy_path == "": |
| return public.returnResult(status=False, msg="proxy_path不能为空!") |
|
|
| get.proxy_host = get.get("proxy_host", "") |
| if get.proxy_host == "": |
| return public.returnResult(status=False, msg="proxy_host不能为空!") |
|
|
| get.proxy_pass = get.get("proxy_pass", "") |
| if get.proxy_pass == "": |
| return public.returnResult(status=False, msg="proxy_pass不能为空!") |
|
|
| get.proxy_type = get.get("proxy_type", "") |
| if get.proxy_type == "": |
| return public.returnResult(status=False, msg="proxy_type不能为空!") |
|
|
| get.proxy_connect_timeout = get.get("proxy_connect_timeout", "60s") |
| get.proxy_send_timeout = get.get("proxy_send_timeout", "600s") |
| get.proxy_read_timeout = get.get("proxy_read_timeout", "600s") |
|
|
| get.remark = get.get("remark", "") |
| if get.remark != "": |
| get.remark = public.xssencode2(get.remark) |
|
|
| if get.proxy_type == "unix": |
| if not get.proxy_pass.startswith("http://unix:"): |
| if not get.proxy_pass.startswith("/"): |
| return public.returnResult(status=False, |
| msg="unix文件路径必须以/或http://unix:开头,如/tmp/flask_app.sock!") |
| if not get.proxy_pass.endswith(".sock"): |
| return public.returnResult(status=False, msg="unix文件必须以.sock结尾,如/tmp/flask_app.sock!") |
| if not os.path.exists(get.proxy_pass): |
| return public.returnResult(status=False, msg="代理目标不存在!") |
| get.proxy_pass = "http://unix:" + get.proxy_pass |
| elif get.proxy_type == "http": |
| if not get.proxy_pass.startswith("http://") and not get.proxy_pass.startswith("https://"): |
| return public.returnResult(status=False, msg="代理目标必须以http://或https://开头!") |
|
|
| get.websocket = get.get("websocket/d", 1) |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| if get.proxy_json_conf["websocket"]["websocket_status"] and get.websocket != 1: |
| return public.returnResult(status=False, |
| msg="全局websocket为开启状态,不允许单独关闭此URL的websocket支持!") |
|
|
| for info in get.proxy_json_conf["proxy_info"]: |
| if info["proxy_path"] == get.proxy_path: |
| info["proxy_host"] = get.proxy_host |
| info["proxy_pass"] = get.proxy_pass |
| info["proxy_type"] = get.proxy_type |
| info["timeout"]["proxy_connect_timeout"] = get.proxy_connect_timeout.replace("s", "") |
| info["timeout"]["proxy_send_timeout"] = get.proxy_send_timeout.replace("s", "") |
| info["timeout"]["proxy_read_timeout"] = get.proxy_read_timeout.replace("s", "") |
| info["websocket"]["websocket_status"] = True if get.websocket == 1 else False |
| info["remark"] = get.remark |
| break |
| else: |
| return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def add_proxy(self, get): |
| ''' |
| @name |
| @author wzz <2024/4/19 下午3:00> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.proxy_path = get.get("proxy_path", "") |
| if get.proxy_path == "": |
| return public.returnResult(status=False, msg="proxy_path不能为空!") |
|
|
| get.proxy_pass = get.get("proxy_pass", "") |
| if get.proxy_pass == "": |
| return public.returnResult(status=False, msg="proxy_pass不能为空!") |
|
|
| get.proxy_host = get.get("proxy_host", "$http_host") |
| get.proxy_type = get.get("proxy_type", "http") |
| get.remark = get.get("remark", "") |
| get.proxy_timeout = "proxy_connect_timeout 60s;\n proxy_send_timeout 600s;\n proxy_read_timeout 600s;" |
|
|
| if get.remark != "": |
| get.remark = public.xssencode2(get.remark) |
| if get.proxy_type == "unix": |
| if not get.proxy_pass.startswith("/"): |
| return public.returnResult(status=False, msg="unix文件路径必须以/开头,如/tmp/flask_app.sock!") |
| if not get.proxy_pass.endswith(".sock"): |
| return public.returnResult(status=False, msg="unix文件必须以.sock结尾,如/tmp/flask_app.sock!") |
| if not os.path.exists(get.proxy_pass): |
| return public.returnResult(status=False, msg="代理目标不存在!") |
|
|
| get.proxy_pass = "http://unix:{}".format(get.proxy_pass) |
| elif get.proxy_type == "http": |
| if not get.proxy_pass.startswith("http://") and not get.proxy_pass.startswith("https://"): |
| return public.returnResult(status=False, msg="代理目标必须以http://或https://开头!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| |
| for proxy_info in get.proxy_json_conf["proxy_info"]: |
| if proxy_info["proxy_path"] == get.proxy_path: |
| return public.returnResult(status=False, |
| msg="【{}】已存在反向代理中,无法重复添加!".format(get.proxy_path)) |
|
|
| if len(get.proxy_json_conf["basic_auth"]) != 0: |
| for i in range(len(get.proxy_json_conf["basic_auth"])): |
| if get.proxy_json_conf["basic_auth"][i]["auth_path"] == get.proxy_path: |
| return public.returnResult(status=False, msg="【{}】已存在basicauth中,请先删除再添加反向代理!".format( |
| get.proxy_path)) |
|
|
| sni_conf = "" |
| if get.proxy_pass.startswith("https://"): |
| sni_conf = "proxy_ssl_server_name on;" |
| get.proxy_conf = self._template_proxy_conf.format( |
| ip_limit="", |
| gzip="", |
| proxy_cache="", |
| sub_filter="", |
| server_log="", |
| basic_auth="", |
| proxy_pass=get.proxy_pass, |
| proxy_host=get.proxy_host, |
| proxy_path=get.proxy_path, |
| SNI=sni_conf, |
| custom_conf="", |
| timeout_conf=get.proxy_timeout, |
| PROXY_BUFFERING="", |
| websocket_support=get.proxy_json_conf["websocket"]["websocket_conf"], |
| ) |
|
|
| get.proxy_json_conf["proxy_info"].append({ |
| "proxy_type": get.proxy_type, |
| "proxy_path": get.proxy_path, |
| "proxy_pass": get.proxy_pass, |
| "proxy_host": get.proxy_host, |
| "ip_limit": { |
| "ip_black": [], |
| "ip_white": [], |
| }, |
| "basic_auth": {}, |
| "proxy_cache": { |
| "cache_status": False, |
| "cache_zone": "", |
| "static_cache": "", |
| "expires": "1d", |
| "cache_conf": "", |
| }, |
| "gzip": { |
| "gzip_status": False, |
| "gzip_min_length": "10k", |
| "gzip_comp_level": "6", |
| "gzip_types": "text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/json image/jpeg image/gif image/png font/ttf font/otf image/svg+xml application/xml+rss text/x-js", |
| "gzip_conf": "gzip on;\n gzip_min_length 10k;\n gzip_buffers 4 16k;\n gzip_http_version 1.1;\n gzip_comp_level 2;\n gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;\n gzip_vary on;\n gzip_proxied expired no-cache no-store private auth;\n gzip_disable \"MSIE [1-6]\.\";", |
| }, |
| "sub_filter": { |
| "sub_filter_str": [], |
| }, |
| "websocket": { |
| "websocket_status": True, |
| "websocket_conf": "proxy_http_version 1.1;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection $connection_upgrade;", |
| }, |
| "proxy_log": { |
| "log_type": "off", |
| "log_conf": "", |
| }, |
| "timeout": { |
| "proxy_connect_timeout": "60", |
| "proxy_send_timeout": "600", |
| "proxy_read_timeout": "600", |
| "timeout_conf": "proxy_connect_timeout 60s;\n proxy_send_timeout 600s;\n proxy_read_timeout 600s;", |
| }, |
| "custom_conf": "", |
| "proxy_conf": get.proxy_conf, |
| "remark": get.remark, |
| "template_proxy_conf": self._template_proxy_conf, |
| }) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="添加成功!") |
|
|
| |
| def del_url_proxy(self, get): |
| ''' |
| @name 删除指定网站指定URL的反向代理 |
| @param get: |
| @return: |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.proxy_path = get.get("proxy_path", "") |
| if get.proxy_path == "": |
| return public.returnResult(status=False, msg="proxy_path不能为空!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| for info in get.proxy_json_conf["proxy_info"]: |
| if info["proxy_path"] == get.proxy_path: |
| get.proxy_json_conf["proxy_info"].remove(info) |
| break |
| else: |
| return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="删除成功!") |
|
|
| |
| def set_url_remark(self, get): |
| ''' |
| @name 设置指定网站指定URL反向代理的备注 |
| @param get: |
| @return: |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.proxy_path = get.get("proxy_path", "") |
| if get.proxy_path == "": |
| return public.returnResult(status=False, msg="proxy_path不能为空!") |
|
|
| get.remark = get.get("remark", "") |
| if get.remark != "": |
| get.remark = public.xssencode2(get.remark) |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| for info in get.proxy_json_conf["proxy_info"]: |
| if info["proxy_path"] == get.proxy_path: |
| info["remark"] = get.remark |
| break |
| else: |
| return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def add_sub_filter(self, get): |
| ''' |
| @name 添加指定网站指定URL的内容替换 |
| @param get: |
| @return: |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.proxy_path = get.get("proxy_path", "") |
| if get.proxy_path == "": |
| return public.returnResult(status=False, msg="proxy_path不能为空!") |
|
|
| get.oldstr = get.get("oldstr", "") |
| get.newstr = get.get("newstr", "") |
|
|
| if get.oldstr == "" and get.newstr == "": |
| return public.returnResult(status=False, msg="oldstr和newstr不能同时为空!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| get.sub_type = get.get("sub_type", "g") |
| if get.sub_type == "": |
| get.sub_type = "g" |
| import re |
| if not re.match(r'^[ior]+$|^g(?!.*o)|^o(?!.*g)$', get.sub_type): |
| return public.returnResult(status=False, |
| msg="get.sub_type 只能包含 'g'、'i'、'o' 或 'r' 中的字母组合,并且 'g' 和 'o' 不能同时存在!") |
|
|
| is_subs = public.ExecShell("nginx -V 2>&1|grep 'ngx_http_substitutions_filter' -o")[0] |
| if not is_subs and re.search(u'[\u4e00-\u9fa5]', get.oldstr + get.newstr): |
| return public.returnResult(status=False, |
| msg="您输入的内容包含中文,检测到当前nginx版本不支持,请尝试重新安装nginx 1.20以上的版本后重试!") |
|
|
| if get.sub_type != "g" and not is_subs: |
| return public.returnResult(status=False, |
| msg="检测到当前nginx版本仅支持默认替换类型,请尝试重新安装nginx 1.20以上的版本后重试!") |
|
|
| if not "g" in get.sub_type and not "o" in get.sub_type: |
| get.sub_type = "g" + get.sub_type |
|
|
| for info in get.proxy_json_conf["proxy_info"]: |
| if info["proxy_path"] == get.proxy_path: |
| for sub in info["sub_filter"]["sub_filter_str"]: |
| if get.oldstr == sub["oldstr"]: |
| return public.returnResult(status=False, |
| msg="替换前内容:【{}】的配置信息已存在,请勿重复添加!".format( |
| get.oldstr)) |
| info["sub_filter"]["sub_filter_str"].append( |
| { |
| "sub_type": get.sub_type, |
| "oldstr": get.oldstr, |
| "newstr": get.newstr |
| } |
| ) |
| break |
| else: |
| return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def del_sub_filter(self, get): |
| ''' |
| @name 删除指定网站指定URL的内容替换 |
| @param get: |
| @return: |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.proxy_path = get.get("proxy_path", "") |
| if get.proxy_path == "": |
| return public.returnResult(status=False, msg="proxy_path不能为空!") |
|
|
| get.oldstr = get.get("oldstr", "") |
| get.newstr = get.get("newstr", "") |
|
|
| if get.oldstr == "" and get.newstr == "": |
| return public.returnResult(status=False, msg="oldstr和newstr不能同时为空!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| for info in get.proxy_json_conf["proxy_info"]: |
| if info["proxy_path"] == get.proxy_path: |
| for sub in info["sub_filter"]["sub_filter_str"]: |
| if get.oldstr == sub["oldstr"]: |
| info["sub_filter"]["sub_filter_str"].remove(sub) |
| break |
| else: |
| return public.returnResult(status=False, |
| msg="未找到替换前内容:【{}】的配置信息!".format(get.oldstr)) |
| break |
| else: |
| return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="删除成功!") |
|
|
| |
| def set_url_gzip(self, get): |
| ''' |
| @name 设置指定网站指定URL的内容压缩 |
| @param get: |
| @return: |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.proxy_path = get.get("proxy_path", "") |
| if get.proxy_path == "": |
| return public.returnResult(status=False, msg="proxy_path不能为空!") |
|
|
| get.gzip_status = get.get("gzip_status/d", 999) |
| if get.gzip_status == 999: |
| return public.returnResult(status=False, msg="gzip_status不能为空,请传number 1或0!") |
| get.gzip_min_length = get.get("gzip_min_length", "10k") |
| get.gzip_comp_level = get.get("gzip_comp_level", "6") |
| if get.gzip_min_length[0] == "0" or get.gzip_min_length.startswith("-"): |
| return public.returnResult(status=False, msg="gzip_min_length参数不合法,请输入大于0的数字!") |
| if get.gzip_comp_level == "0" or get.gzip_comp_level.startswith("-"): |
| return public.returnResult(status=False, msg="gzip_comp_level参数不合法,请输入大于0的数字!") |
| get.gzip_types = get.get( |
| "gzip_types", |
| "text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/json image/jpeg image/gif image/png font/ttf font/otf image/svg+xml application/xml+rss text/x-js" |
| ) |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| for info in get.proxy_json_conf["proxy_info"]: |
| if info["proxy_path"] == get.proxy_path: |
| info["gzip"]["gzip_status"] = True if get.gzip_status == 1 else False |
| if get.gzip_status == 1: |
| info["gzip"]["gzip_types"] = get.gzip_types |
| info["gzip"]["gzip_min_length"] = get.gzip_min_length |
| info["gzip"]["gzip_comp_level"] = get.gzip_comp_level |
| info["gzip"]["gzip_conf"] = ("gzip on;" |
| "\n gzip_min_length {gzip_min_length};" |
| "\n gzip_buffers 4 16k;" |
| "\n gzip_http_version 1.1;" |
| "\n gzip_comp_level {gzip_comp_level};" |
| "\n gzip_types {gzip_types};" |
| "\n gzip_vary on;" |
| "\n gzip_proxied expired no-cache no-store private auth;" |
| "\n gzip_disable \"MSIE [1-6]\.\";").format( |
| gzip_min_length=get.gzip_min_length, |
| gzip_comp_level=get.gzip_comp_level, |
| gzip_types=get.gzip_types, |
| ) |
| else: |
| info["gzip"]["gzip_conf"] = "" |
| break |
| else: |
| return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def add_url_ip_limit(self, get): |
| ''' |
| @name 添加指定网站指定URL的IP黑白名单 |
| @author wzz <2024/4/22 下午10:16> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.proxy_path = get.get("proxy_path", "") |
| if get.proxy_path == "": |
| return public.returnResult(status=False, msg="proxy_path不能为空!") |
|
|
| get.ip_type = get.get("ip_type", "black") |
| if get.ip_type not in ["black", "white"]: |
| return public.returnResult(status=False, msg="ip_type参数错误,必须传black或white!") |
|
|
| get.ips = get.get("ips", "") |
| if get.ips == "": |
| return public.returnResult(status=False, msg="ips不能为空,请输入IP,一行一个!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| get.ips = get.ips.split("\n") |
| for info in get.proxy_json_conf["proxy_info"]: |
| if info["proxy_path"] == get.proxy_path: |
| for ip in get.ips: |
| if get.ip_type == "black": |
| if not ip in info["ip_limit"]["ip_black"]: |
| info["ip_limit"]["ip_black"].append(ip) |
| else: |
| if not ip in info["ip_limit"]["ip_white"]: |
| info["ip_limit"]["ip_white"].append(ip) |
| break |
| else: |
| return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def del_url_ip_limit(self, get): |
| ''' |
| @name 删除指定网站指定URL的IP黑白名单 |
| @param get: |
| @return: |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.proxy_path = get.get("proxy_path", "") |
| if get.proxy_path == "": |
| return public.returnResult(status=False, msg="proxy_path不能为空!") |
|
|
| get.ip_type = get.get("ip_type", "black") |
| if get.ip_type not in ["black", "white"]: |
| return public.returnResult(status=False, msg="ip_type参数错误,必须传black或white!") |
|
|
| get.ip = get.get("ip", "") |
| if get.ip == "": |
| return public.returnResult(status=False, msg="ip不能为空,请输入IP!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| for info in get.proxy_json_conf["proxy_info"]: |
| if info["proxy_path"] == get.proxy_path: |
| if get.ip in info["ip_limit"]["ip_{ip_type}".format(ip_type=get.ip_type)]: |
| info["ip_limit"]["ip_{ip_type}".format(ip_type=get.ip_type)].remove(get.ip) |
| break |
| else: |
| return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def batch_del_url_ip_limit(self, get): |
| ''' |
| @name 批量删除指定网站指定URL的IP黑白名单 |
| @author wzz <2024/4/24 上午11:22> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.ip_type = get.get("ip_type", "black") |
| if get.ip_type not in ["black", "white", "all"]: |
| return public.returnResult(status=False, msg="ip_type参数错误,必须传black或white!") |
|
|
| get.ips = get.get("ips", "") |
| if get.ips == "": |
| return public.returnResult(status=False, msg="ips不能为空,请输入IP,一行一个!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| for info in get.proxy_json_conf["proxy_info"]: |
| if info["proxy_path"] == get.proxy_path: |
| get.ips = get.ips.split("\n") |
| if get.ip_type == "all": |
| for ip in get.ips: |
| if ip in info["ip_limit"]["ip_black"]: |
| info["ip_limit"]["ip_black"].remove(ip) |
| if ip in info["ip_limit"]["ip_white"]: |
| info["ip_limit"]["ip_white"].remove(ip) |
| else: |
| for ip in get.ips: |
| if ip in info["ip_limit"]["ip_{ip_type}".format(ip_type=get.ip_type)]: |
| info["ip_limit"]["ip_{ip_type}".format(ip_type=get.ip_type)].remove(ip) |
| break |
| else: |
| return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="删除成功!") |
|
|
| |
| def set_url_cache(self, get): |
| ''' |
| @name 设置指定网站指定URL的缓存 |
| @param get: |
| @return: |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.cache_status = get.get("cache_status/d", 999) |
| if get.cache_status == 999: |
| return public.returnResult(status=False, msg="cache_status不能为空,请传number 1或0!") |
|
|
| get.expires = get.get("expires", "1d") |
| if get.expires[0] == "0" or get.expires.startswith("-"): |
| return public.returnResult(status=False, msg="expires参数不合法,请输入大于0的数字!") |
|
|
| expires = "expires {}".format(get.expires) |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| static_cache = ("\n location ~ .*\\.(css|js|jpe?g|gif|png|webp|woff|eot|ttf|svg|ico|css\.map|js\.map)$" |
| "\n {{" |
| "\n {expires};" |
| "\n error_log /dev/null;" |
| "\n access_log /dev/null;" |
| "\n }}").format( |
| expires=expires, |
| ) |
|
|
| for info in get.proxy_json_conf["proxy_info"]: |
| if info["proxy_path"] == get.proxy_path: |
| info["proxy_cache"]["cache_status"] = True if get.cache_status == 1 else False |
| info["proxy_cache"]["expires"] = get.expires |
| if get.cache_status == 1: |
| info["proxy_cache"]["cache_conf"] = ("\n proxy_cache {cache_zone};" |
| "\n proxy_cache_key $host$uri$is_args$args;" |
| "\n proxy_ignore_headers Set-Cookie Cache-Control expires X-Accel-Expires;" |
| "\n proxy_cache_valid 200 304 301 302 {expires};" |
| "\n proxy_cache_valid 404 1m;" |
| "{static_cache}").format( |
| cache_zone=get.proxy_json_conf["proxy_cache"]["cache_zone"], |
| expires=get.expires, |
| static_cache=static_cache, |
| ) |
| else: |
| info["proxy_cache"]["cache_conf"] = "" |
| break |
| else: |
| return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def set_url_custom_conf(self, get): |
| ''' |
| @name 设置指定网站指定URL的自定义配置 |
| @author wzz <2024/4/24 上午9:58> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.proxy_path = get.get("proxy_path", "") |
| if get.proxy_path == "": |
| return public.returnResult(status=False, msg="proxy_path不能为空!") |
|
|
| get.custom_conf = get.get("custom_conf", "") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| for info in get.proxy_json_conf["proxy_info"]: |
| if info["proxy_path"] == get.proxy_path: |
| info["custom_conf"] = get.custom_conf |
| break |
| else: |
| return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def GetSiteLogs(self, get): |
| ''' |
| @name 获取指定网站的网站日志 |
| @author wzz <2024/4/24 下午5:39> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.type = get.get("type", "access") |
| log_name = get.site_name |
| if get.type != "access": |
| log_name = get.site_name + ".error" |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| if get.proxy_json_conf["proxy_log"]["log_type"] == "default": |
| log_file = public.get_logs_path() + "/" + log_name + '.log' |
| elif get.proxy_json_conf["proxy_log"]["log_type"] == "file": |
| log_file = get.proxy_json_conf["proxy_log"]["log_path"] + "/" + log_name + '.log' |
| else: |
| return public.returnResult(data={"msg": "", "size": 0}) |
|
|
| if os.path.exists(log_file): |
| return public.returnResult( |
| data={ |
| "msg": self.xsssec(public.GetNumLines(log_file, 1000)), |
| "size": public.to_size(os.path.getsize(log_file)) |
| } |
| ) |
|
|
| return public.returnResult(data={"msg": "", "size": 0}) |
|
|
| |
| def clear_cache(self, get): |
| ''' |
| @name 清理指定网站的反向代理缓存 |
| @author wzz <2024/4/25 上午10:51> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| cache_dir = "{sites_config_path}/{site_name}/proxy_cache_dir".format(sites_config_path=self.sites_config_path, site_name=get.site_name) |
| if os.path.exists(cache_dir): |
| public.ExecShell("rm -rf {cache_dir}/*".format(cache_dir=cache_dir)) |
|
|
| public.serviceReload() |
| return public.returnResult(msg="清理成功!") |
|
|
| return public.returnResult(msg="清理失败,缓存目录不存在!") |
|
|
| |
| def set_https_port(self, get): |
| ''' |
| @name 设置指定网站的https端口 |
| @author wzz <2024/4/25 下午9:24> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.https_port = get.get("https_port", "443") |
| if not public.checkPort(get.https_port) and get.https_port != "443": |
| return public.returnResult(status=False, msg="https端口【{}】不合法!".format(get.https_port)) |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| get.proxy_json_conf["https_port"] = get.https_port |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def save_block_config(self, get): |
| ''' |
| @name 保存配置文件 |
| @param get: |
| @return: |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.conf_type = get.get("conf_type", "") |
| if get.conf_type == "": |
| return public.returnResult(status=False, msg="conf_type不能为空!") |
|
|
| get.body = get.get("body", "") |
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| if get.conf_type == "http_block": |
| get.proxy_json_conf["http_block"] = get.body |
| else: |
| get.proxy_json_conf["server_block"] = get.body |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="保存成功!") |
|
|
| |
| def get_nginx_config(self, get): |
| ''' |
| @name |
| @author wzz <2024/4/20 下午2:22> |
| @param "data":{"参数名":""} <数据类型> 参数描述 |
| @return dict{"status":True/False,"msg":"提示信息"} |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| site_conf = public.readFile(public.get_setup_path() + '/panel/vhost/nginx/' + get.site_name + '.conf') |
| ssl_conf = get.proxy_json_conf["ssl_info"]["ssl_conf"].format( |
| site_name=get.site_name, |
| ) |
| if get.proxy_json_conf["ssl_info"]["force_https"]: |
| ssl_conf = get.proxy_json_conf["ssl_info"]["force_ssl_conf"].format( |
| site_name=get.site_name, |
| force_conf=get.proxy_json_conf["ssl_info"]["force_ssl_conf"], |
| ) |
|
|
| if "如果反代网站访问异常且这里已经配置了内容,请优先排查此处的配置是否正确" in get.proxy_json_conf[ |
| "http_block"]: |
| http_block = get.proxy_json_conf["http_block"] |
| else: |
| http_block = '''# 可设置server|upstream|map等所有http字段,如: |
| # server {{ |
| # listen 10086; |
| # server_name ... |
| # }} |
| # upstream stream_ser {{ |
| # server back_test.com; |
| # server ... |
| # }} |
| {default_describe} |
| {http_block}'''.format( |
| default_describe=self.init_site_json["default_describe"], |
| http_block=get.proxy_json_conf["http_block"], |
| ) |
|
|
| if "如果反代网站访问异常且这里已经配置了内容,请优先排查此处的配置是否正确" in get.proxy_json_conf[ |
| "server_block"]: |
| server_block = get.proxy_json_conf["server_block"] |
| else: |
| server_block = '''# 可设置server|location等所有server字段,如: |
| # location /web {{ |
| # try_files $uri $uri/ /index.php$is_args$args; |
| # }} |
| # error_page 404 /diy_404.html; |
| {default_describe} |
| {server_block}'''.format( |
| default_describe=self.init_site_json["default_describe"], |
| server_block=get.proxy_json_conf["server_block"], |
| ) |
|
|
| data = { |
| "site_conf": site_conf if not site_conf is False else "", |
| "http_block": http_block, |
| "server_block": server_block, |
| "ssl_conf": ssl_conf, |
| } |
|
|
| return public.returnResult(data=data) |
|
|
| |
| def get_domain_list(self, get): |
| ''' |
| @name 获取域名列表和https端口 |
| @param get: |
| @return: |
| ''' |
| get.id = get.get("id", "") |
| if get.id == "": |
| return public.returnResult(status=False, msg="id不能为空!") |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| select_result = dp.sql("docker_domain").where("pid=?", get.id).select() |
| if not select_result: |
| return public.returnResult(status=False, msg="未找到此ID【{}】的域名信息!".format(get.id)) |
|
|
| |
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| result_data = {} |
| result_data["domain_list"] = select_result |
| if get.proxy_json_conf["ssl_info"]["ssl_status"]: |
| if not "https_port" in get.proxy_json_conf or get.proxy_json_conf["https_port"] == "": |
| get.proxy_json_conf["https_port"] = "443" |
| result_data["https_port"] = get.proxy_json_conf["https_port"] |
| else: |
| result_data["https_port"] = "未开启HTTPS" |
|
|
| |
| for domain in result_data["domain_list"]: |
| domain["healthy"] = 1 |
| if domain["name"] not in get.proxy_json_conf["domain_list"]: |
| domain["healthy"] = 0 |
|
|
| return public.returnResult(data=result_data) |
|
|
| |
| def set_site_rewrite(self, get): |
| ''' |
| @name 设置指定网站的伪静态 |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.rewrite_conf = get.get("rewrite_conf", "") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| get.proxy_json_conf["rewrite_conf"] = get.rewrite_conf |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def get_site_rewrite(self, get): |
| ''' |
| @name 获取指定网站的伪静态 |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| return public.returnResult(data=get.proxy_json_conf["rewrite_conf"]) |
|
|
| |
| def set_site_ipv6(self, get): |
| ''' |
| @name 设置指定网站监听IPv6 |
| ''' |
| get.site_name = get.get("site_name", "") |
| if get.site_name == "": |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| get.ipv6_status = get.get("ipv6_status/d", 0) |
|
|
| get.proxy_json_conf["ipv6_status"] = True if get.ipv6_status == 1 else False |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def get_index(self, get): |
| ''' |
| @name 获取指定网站的默认文档 |
| ''' |
| get.id = get.get("id", None) |
| if get.id is None: return public.returnResult(status=False, msg="id不能为空!") |
| get.site_name = get.get("site_name", None) |
| if get.site_name is None: return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| return public.returnResult(True, data=get.proxy_json_conf["index_conf"].replace(" ", "\n")) |
|
|
| |
| def set_index(self, get): |
| ''' |
| @name 设置指定网站的默认文档 |
| ''' |
| get.id = get.get("id", None) |
| if get.id is None: return public.returnResult(status=False, msg="id不能为空!") |
| get.site_name = get.get("site_name", None) |
| if get.site_name is None: return public.returnResult(status=False, msg="site_name不能为空!") |
| get.index = get.get("index", None) |
| if get.index is None: return public.returnResult(status=False, msg="index不能为空!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| get.proxy_json_conf["index_conf"] = get.index.replace("\n", " ") |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| def read_file(self, path): |
| ''' |
| @name |
| ''' |
| data = {} |
| try: |
| fp = open(path, 'rb') |
| if fp: |
| srcBody = fp.read() |
| fp.close() |
| try: |
| data['encoding'] = 'utf-8' |
| data['data'] = srcBody.decode(data['encoding']) |
| except: |
| try: |
| data['encoding'] = 'GBK' |
| data['data'] = srcBody.decode(data['encoding']) |
| except: |
| try: |
| data['encoding'] = 'BIG5' |
| data['data'] = srcBody.decode(data['encoding']) |
| except: |
| return public.returnResult(False, '文件编码不被兼容,无法正确读取文件!') |
| except OSError as e: |
| return public.returnResult(False, '打开文件失败,文件可能被其它进程占用!') |
| except Exception as e: |
| return public.returnResult(False, '打开文件失败,{}'.format(str(e))) |
|
|
| return data |
|
|
| |
| def get_default_body(self, get): |
| ''' |
| @name 获取指定默认页面内容 |
| ''' |
| get.default_type = get.get("default_type", "all") |
| if not get.default_type in ("all", "index", "404", "not_found", "stop"): |
| return public.returnResult(status=False, msg="default_type参数错误!") |
|
|
| pl_path = os.path.join(self.sites_config_path, "no_auto_create_404.pl") |
| auto_create_404 = True if not os.path.exists(pl_path) else False |
|
|
| if get.default_type == "not_found": |
| not_found_body = self.read_file("/www/server/nginx/html/index.html") |
| if not "encoding" in not_found_body: |
| public.writeFile("/www/server/nginx/html/index.html", getattr(self, "default_not_found_body")) |
| not_found_body = {"default_not_found_body": getattr(self, "default_not_found_body"), "encoding": "utf-8"} |
| return public.returnResult(True, data={"not_found": not_found_body, "auto_create_404": auto_create_404}) |
|
|
| if get.default_type != "all": |
| diy_filename = os.path.join(self.sites_config_path, "default_{}.html".format(get.default_type)) |
| if not os.path.exists(diy_filename): |
| if os.path.isfile("/www/dk_project/runtime/templates/html/default_{}.html".format(get.default_type)): |
| public.writeFile(diy_filename, public.readFile("/www/dk_project/runtime/templates/html/default_{}.html".format(get.default_type))) |
| else: |
| public.writeFile(diy_filename, getattr(self, "default_{}_body".format(get.default_type))) |
|
|
| diy_body = self.read_file(diy_filename) |
| if not "encoding" in diy_body: |
| public.writeFile(diy_filename, getattr(self, "default_{}_body".format(get.default_type))) |
| return public.returnResult(True, data={"default_{}_body".format(get.default_type): getattr(self, "default_{}_body".format(get.default_type)), "encoding": "utf-8"}) |
|
|
| return public.returnResult(True, data={get.default_type: diy_body, "auto_create_404": auto_create_404}) |
| else: |
| return_result = {} |
| for default_type in ("index", "404", "stop"): |
| diy_filename = os.path.join(self.sites_config_path, "default_{}.html".format(default_type)) |
| if not os.path.exists(diy_filename): |
| if os.path.isfile("/www/dk_project/runtime/templates/html/default_{}.html".format(default_type)): |
| public.writeFile(diy_filename, public.readFile("/www/dk_project/runtime/templates/html/default_{}.html".format(default_type))) |
| else: |
| public.writeFile(diy_filename, getattr(self, "default_{}_body".format(default_type))) |
|
|
| diy_body = self.read_file(diy_filename) |
| if not "encoding" in diy_body: |
| public.writeFile(diy_filename, getattr(self, "default_{}_body".format(default_type))) |
| return_result[default_type] = {"default_{}_body".format(default_type): getattr(self, "default_{}_body".format(default_type)), "encoding": "utf-8"} |
| else: |
| return_result[default_type] = diy_body |
|
|
| not_found_body = self.read_file("/www/server/nginx/html/index.html") |
| if not "encoding" in not_found_body: |
| public.writeFile("/www/server/nginx/html/index.html", getattr(self, "default_not_found_body")) |
| not_found_body = {"default_not_found_body": getattr(self, "default_not_found_body"), "encoding": "utf-8"} |
| return_result["not_found"] = not_found_body |
| return_result["auto_create_404"] = auto_create_404 |
|
|
| return public.returnResult(True, data=return_result) |
|
|
| |
| def set_default_body(self, get): |
| ''' |
| @name 修改指定默认页面内容 |
| ''' |
| get.default_type = get.get("default_type", None) |
| if not get.default_type in ("index", "404", "not_found", "stop"): |
| return public.returnResult(status=False, msg="default_type参数错误!") |
| get.encoding = get.get("encoding", "utf-8") |
|
|
| get.default_body = get.get("default_body", None) |
| if not get.default_body: |
| return public.returnResult(status=False, msg="default_body不能为空!") |
|
|
| |
| if not re.match(r"<html.*?>.*?</html>", get.default_body, re.S) and not re.match(r"<.*?doctype.*?html>", get.default_body, re.S): |
| return public.returnResult(status=False, msg="必须输入html内容!") |
|
|
| if get.default_type == "not_found": |
| public.writeFile("/www/server/nginx/html/index.html", get.default_body) |
| return public.returnResult(msg="设置成功!") |
|
|
| diy_filename = os.path.join(self.sites_config_path, "default_{}.html".format(get.default_type)) |
|
|
| get.path = diy_filename |
| get.data = get.default_body |
| import files |
| f = files.files() |
| return f.SaveFileBody(get) |
|
|
| |
| def set_auto_create_404(self, get): |
| ''' |
| @name 设置是否在创建网站时自动创建404.html页面 |
| ''' |
| get.auto_create = get.get("auto_create", 1) |
| pl_path = os.path.join(self.sites_config_path, "no_auto_create_404.pl") |
|
|
| if int(get.auto_create) == 0: |
| public.writeFile(pl_path, "False") |
| else: |
| public.ExecShell("rm -f {}".format(pl_path)) |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def set_404_status(self, get): |
| ''' |
| @name 设置指定网站404页面的开启状态 |
| ''' |
| get.site_name = get.get("site_name", None) |
| if not get.site_name: |
| return public.returnResult(status=False, msg="site_name不能为空!") |
| get.status = get.get("status", 0) |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| if int(get.status) == 1: |
| err_age_404 = "error_page 404 /404.html;" |
| else: |
| err_age_404 = "#error_page 404 /404.html;" |
|
|
| get.proxy_json_conf["err_age_404"] = err_age_404 |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def set_404_body(self, get): |
| ''' |
| @name 设置指定网站的404.html页面内容 |
| ''' |
| get.site_name = get.get("site_name", None) |
| if not get.site_name: |
| return public.returnResult(status=False, msg="site_name不能为空!") |
| get.file_body = get.get("file_body", "") |
| get.encoding = get.get("encoding", "utf-8") |
|
|
| |
| if not re.match(r"<html.*?>.*?</html>", get.file_body, re.S) and not re.match(r"<.*?doctype.*?html>", get.file_body, re.S): |
| return public.returnResult(status=False, msg="必须输入html内容!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| get.site_path = get.proxy_json_conf["site_path"] |
| get.run_path = get.proxy_json_conf["run_path"] |
|
|
| if get.run_path == "/": |
| file_path = os.path.join(get.site_path, "404.html") |
| else: |
| file_path = os.path.join(get.site_path, get.run_path, "404.html") |
| get.path = file_path |
| get.data = get.file_body |
| import files |
| f = files.files() |
| return f.SaveFileBody(get) |
|
|
| |
| def get_404_body(self, get): |
| ''' |
| @name 获取指定网站的404.html页面内容 |
| ''' |
| get.site_name = get.get("site_name", None) |
| if not get.site_name: |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| get.site_path = get.proxy_json_conf["site_path"] |
| get.run_path = get.proxy_json_conf["run_path"] |
|
|
| if get.run_path == "/": |
| file_path = os.path.join(get.site_path, "404.html") |
| else: |
| file_path = os.path.join(get.site_path, get.run_path, "404.html") |
|
|
| get.path = file_path |
| import files |
| f = files.files() |
| read_result = f.GetFileBody(get) |
| if not read_result["status"]: |
| return { |
| "auto_save": None, |
| "data": "", |
| "encoding": "utf-8", |
| "historys": [], |
| "only_read": False, |
| "size": 0, |
| "st_mtime": str(int(time.time())), |
| "status": True, |
| } |
| return read_result |
|
|
| |
| def create_default_html(self, get): |
| ''' |
| @name 创建默认html文件 |
| ''' |
| self.get_default_body(get) |
|
|
| if not os.path.exists(os.path.join(get.site_path, 'index.html')): |
| public.writeFile(os.path.join(get.site_path, 'index.html'), public.readFile(os.path.join(self.sites_config_path, "default_index.html"))) |
| public.ExecShell('chown www:www {}'.format(os.path.join(get.site_path, 'index.html'))) |
| public.ExecShell('chmod 755 {}'.format(os.path.join(get.site_path, 'index.html'))) |
| if not os.path.exists(os.path.join(self.sites_config_path, "no_auto_create_404.pl")): |
| if not os.path.exists(os.path.join(get.site_path, '404.html')): |
| public.writeFile(os.path.join(get.site_path, '404.html'), public.readFile(os.path.join(self.sites_config_path, "default_404.html"))) |
| public.ExecShell('chown www:www {}'.format(os.path.join(get.site_path, '404.html'))) |
| public.ExecShell('chmod 755 {}'.format(os.path.join(get.site_path, '404.html'))) |
| if not os.path.isdir(os.path.join(self.sites_config_path, "stop")): |
| os.makedirs(os.path.join(self.sites_config_path, "stop")) |
| public.ExecShell('chown -R www:www {}'.format(os.path.join(self.sites_config_path, "stop"))) |
| public.ExecShell('chmod -R 755 {}'.format(os.path.join(self.sites_config_path, "stop"))) |
| if not os.path.isfile(os.path.join(self.sites_config_path, "stop/index.html")): |
| public.writeFile(os.path.join(self.sites_config_path, "stop/index.html"), public.readFile(os.path.join(self.sites_config_path, "default_stop.html"))) |
| public.ExecShell('chown www:www {}'.format(os.path.join(self.sites_config_path, "stop/index.html"))) |
| public.ExecShell('chmod 755 {}'.format(os.path.join(self.sites_config_path, "stop/index.html"))) |
|
|
| |
| def get_default_site(self, get): |
| ''' |
| @name 获取默认站点 |
| ''' |
| site_names = dp.sql("docker_sites").where("status=?", 1).field("name").order("id desc").select() |
| default_site = public.readFile('/www/server/panel/data/defaultSite.pl') |
| return public.returnResult(True, data={"sites": site_names, "defaultSite": default_site}) |
|
|
| |
| def set_default_site(self, get): |
| ''' |
| @name 设置默认站点 |
| ''' |
| get.site_name = get.get("site_name", "") |
| if not get.site_name: |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| old_default_site = public.readFile('/www/server/panel/data/defaultSite.pl') |
| if not old_default_site: |
| if get.site_name == "0": |
| public.ExecShell("rm -f /www/server/panel/data/defaultSite.pl") |
| return public.returnResult(msg="设置成功!") |
|
|
| if old_default_site == get.site_name: |
| return public.returnResult(status=False, msg="此站点已经是默认站点!") |
| else: |
| public.ExecShell("rm -f /www/server/panel/data/defaultSite.pl") |
|
|
| args = public.dict_obj() |
| args.site_name = old_default_site |
| args.proxy_json_conf = self.read_json_conf(args) |
|
|
| if args.proxy_json_conf: |
| update_result = self.update_nginx_conf(args) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
|
|
| if get.site_name == "0": |
| public.ExecShell("rm -f /www/server/panel/data/defaultSite.pl") |
| return public.returnResult(msg="设置成功!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| public.writeFile('/www/server/panel/data/defaultSite.pl', get.site_name) |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def sync_docker_sites(self, get): |
| ''' |
| @name 将原来反代项目里面所有docker的反代写入新的docker_sites数据库中 |
| @param get: |
| @return: |
| ''' |
| |
| old_proxy_sites = public.M("sites").where("project_type=?", ("proxy",)).select() |
|
|
| from safeModel.firewallModel import main as firewall_main |
| from mod.project.proxy.comMod import main as proxy_main |
|
|
| for old_site in old_proxy_sites: |
| p_json_file = "/www/server/proxy_project/sites/{site_name}/{site_name}.json".format(site_name=old_site["name"]) |
| if not os.path.exists(p_json_file): continue |
| args = public.dict_obj() |
| args.site_name = old_site["name"] |
| get.proxy_json_conf = proxy_main().read_json_conf(args) |
| if not get.proxy_json_conf: continue |
|
|
| if not "proxy_info" in get.proxy_json_conf: continue |
| if len(get.proxy_json_conf["proxy_info"]) < 1: continue |
| public.writeFile(os.path.join(self.sites_config_path, "{site_name}.json".format(site_name=old_site["name"])), json.dumps(get.proxy_json_conf)) |
|
|
| for proxy_info in get.proxy_json_conf["proxy_info"]: |
| if not "proxy_pass" in proxy_info: continue |
| if not proxy_info["proxy_pass"]: continue |
|
|
| proxy_port = proxy_info["proxy_pass"].split(":")[-1] |
| args = public.dict_obj() |
| args.port = proxy_port |
| res_dict = firewall_main().get_listening_processes(args) |
| if not "process_name" in res_dict: continue |
| if not res_dict["process_name"]: continue |
| if "docker" in res_dict["process_name"]: |
|
|
| container_id = None |
| project_name = None |
| dk_site_info = dp.sql('dk_sites').where('name=?', (old_site["name"],)).find() |
| if dk_site_info: |
| container_id = dk_site_info["container_id"] |
| project_name = dk_site_info["container_name"] |
|
|
| get.service_info = { |
| "name": old_site["name"], |
| "port": args.port, |
| "project_name": project_name, |
| "project_path": None, |
| } |
| get.old_info = json.dumps(old_site) |
|
|
| pdata = { |
| "name": old_site["name"], |
| "path": old_site["path"], |
| "run_path": "/", |
| "remark": public.xssencode2(old_site["ps"]), |
| "type": "proxy", |
| "service_info": json.dumps(get.service_info), |
| "old_info": get.old_info, |
| "addtime": old_site["addtime"], |
| "container_id": container_id, |
| } |
|
|
| get.pid = dp.sql("docker_sites").insert(pdata) |
| if not get.pid: |
| break |
|
|
| domain_list = public.M("domain").where("pid=?", (old_site["id"],)).field("name").find() |
| for domain in domain_list: |
| dp.sql("docker_domain").insert({ |
| "name": domain, |
| "pid": get.pid, |
| "port": "80" if ":" not in domain else domain.split(":")[1], |
| "addtime": old_site["addtime"], |
| }) |
| break |
|
|
| public.writeFile("{}/synced_docker_sites.pl".format(self.sites_config_path), "True") |
|
|
| return public.returnResult(True) |
|
|
| |
| def get_site_types(self, get): |
| ''' |
| @name 获取分类列表 |
| ''' |
| now_time = public.getDate() |
| check_default_result = dp.sql("docker_site_classifys").where("name=?", ("默认分类",)).find() |
| if not check_default_result: |
| dp.sql("docker_site_classifys").insert({ |
| "id": 0, |
| "name": "默认分类", |
| "ps": "默认分类", |
| "addtime": now_time |
| }) |
| check_stop_result = dp.sql("docker_site_classifys").where("name=?", ("已停止的网站",)).find() |
| if not check_stop_result: |
| dp.sql("docker_site_classifys").insert({ |
| "id": -2, |
| "name": "已停止的网站", |
| "ps": "已停止的网站", |
| "addtime": now_time |
| }) |
|
|
| |
| classify_list = dp.sql("docker_site_classifys").order("id desc").select() |
|
|
| |
| new_classify_list = [] |
| for classify in classify_list: |
| if classify["id"] == 0: |
| new_classify_list.insert(0, classify) |
| elif classify["id"] == -2: |
| new_classify_list.insert(1, classify) |
| else: |
| new_classify_list.append(classify) |
|
|
| return public.returnResult(True, data=new_classify_list) |
|
|
| |
| def add_site_type(self, get): |
| ''' |
| @name 添加分类 |
| ''' |
| get.name = get.get("name", "") |
| if not get.name: |
| return public.returnResult(status=False, msg="name不能为空!") |
|
|
| get.ps = get.get("ps", "") |
| now_time = public.getDate() |
| get.id = dp.sql("docker_site_classifys").insert({ |
| "name": public.xssencode2(get.name), |
| "ps": public.xssencode2(get.ps), |
| "addtime": now_time |
| }) |
|
|
| return public.returnResult(msg="添加成功!") |
|
|
| |
| def edit_site_type(self, get): |
| ''' |
| @name 编辑分类 |
| ''' |
| get.id = get.get("id", "") |
| if not get.id: |
| return public.returnResult(status=False, msg="id不能为空!") |
|
|
| get.name = get.get("name", "") |
| if not get.name: |
| return public.returnResult(status=False, msg="name不能为空!") |
|
|
| get.ps = get.get("ps", "") |
| now_time = public.getDate() |
| dp.sql("docker_site_classifys").where("id=?", (get.id,)).update({ |
| "name": public.xssencode2(get.name), |
| "ps": public.xssencode2(get.ps), |
| "addtime": now_time |
| }) |
|
|
| return public.returnResult(msg="编辑成功!") |
|
|
| |
| def del_site_type(self, get): |
| ''' |
| @name 删除分类 |
| ''' |
| get.id = get.get("id", "") |
| if not get.id: |
| return public.returnResult(status=False, msg="id不能为空!") |
|
|
| dp.sql("docker_site_classifys").where("id=?", (get.id,)).delete() |
|
|
| |
| dp.sql("docker_sites").where("classify=?", (get.id,)).update({"classify": 0}) |
| return public.returnResult(msg="删除成功!") |
|
|
| |
| def set_site_type(self, get): |
| ''' |
| @name 为指定网站设置分类 |
| ''' |
| get.id = get.get("id", None) |
| if get.id is None: |
| return public.returnResult(status=False, msg="id不能为空!") |
|
|
| get.classify = get.get("classify", 0) |
|
|
| if type(get.id) == str: |
| try: |
| get.id = json.loads(get.id) |
| except: |
| return public.returnResult(status=False, msg="id参数错误!") |
|
|
| for id in get.id: |
| dp.sql("docker_sites").where("id=?", (id,)).update({"classify": get.classify}) |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| def GetSiteDomain(self,get): |
| """ |
| @name 获取网站域名对应的站点名 |
| @param cert_list 证书域名列表 |
| @auther hezhihong |
| return 证书域名对应的站点名字典,如证书域名未绑定则为空 |
| """ |
| all_site=[] |
| cert_list=[] |
| site_list=[] |
| all_domain = [] |
| try: |
| cert_list=json.loads(get.cert_list) |
| except:pass |
| result={} |
| |
| all_sites=public.M('docker_sites').field('name').select() |
| for site in all_sites: |
| all_site.append(site['name']) |
| if not cert_list:continue |
| tmp_dict={} |
| tmp_dict['name']=site['name'] |
| pid = public.M('docker_sites').where("name=?",(site['name'],)).getField('id') |
| domain_list=public.M('docker_domain').where("pid=?",(pid,)).field('name').select() |
| for domain in domain_list: |
| all_domain.append(domain['name']) |
| |
| site_domain=[] |
| if cert_list and all_domain: |
| for cert in cert_list: |
| d_cert='' |
| if re.match("^\*\..*",cert): |
| d_cert=cert.replace('*.','') |
| for domain in all_domain: |
| if cert == domain: |
| site_domain.append(domain) |
| else: |
| replace_str=domain.split('.')[0]+'.' |
| if d_cert and d_cert==domain.replace(replace_str,''): |
| site_domain.append(domain) |
| |
| for site in site_domain: |
| site_id=public.M('docker_domain').where("name=?",(site,)).getField('pid') |
| site_name=public.M('docker_sites').where("id=?",(site_id,)).getField('name') |
| site_list.append(site_name) |
| site_list=sorted(set(site_list),key=site_list.index) |
| result['all']=all_site |
| result['site']=site_list |
| return result |
|
|
| |
| def GetDirUserINI(self, get): |
| ''' |
| @name 获取防跨站状态和运行目录信息 |
| ''' |
| get.id = get.get("id", None) |
| if not get.id: |
| return public.returnResult(status=False, msg="id不能为空!") |
|
|
| find_result = dp.sql("docker_sites").where("id=?", get.id).find() |
| if not find_result: |
| return public.returnResult(status=False, msg="未找到此ID【{}】的站点信息!".format(get.id)) |
|
|
| data = {'userini': False} |
| user_ini_file = os.path.join(find_result["path"], ".user.ini") |
| try: |
| user_ini_conf = public.readFile(user_ini_file) |
| except OSError: |
| user_ini_conf = {} |
| if user_ini_conf and "open_basedir" in user_ini_conf: |
| data['userini'] = True |
|
|
| |
| p_data = {} |
| path = find_result["path"] |
|
|
| filename = os.path.join(public.get_setup_path(), 'panel/vhost/nginx', find_result["name"] + '.conf') |
| if os.path.exists(filename): |
| conf = public.readFile(filename) |
| rep = '\s*root\s+(.+);' |
| tmp1 = re.search(rep, conf) |
| if tmp1: path = tmp1.groups()[0] |
|
|
| if find_result["path"] == path: |
| p_data['runPath'] = '/' |
| else: |
| p_data['runPath'] = path.replace(find_result["path"], '') |
|
|
| dirnames = [] |
| dirnames.append('/') |
| if not os.path.exists(find_result["path"]): os.makedirs(find_result["path"]) |
|
|
| dirnames = [] |
| if os.path.exists(find_result["path"]): |
| dirnames = ['/' + entry.name for entry in os.scandir(find_result["path"]) if entry.is_dir() and not entry.is_symlink() and entry.name != '.well-known' and entry.name != "proxy_cache_dir"] |
| p_data['dirs'] = ['/'] + dirnames |
|
|
| data['runPath'] = p_data |
|
|
| return public.returnResult(True, data=data) |
|
|
| |
| def SetDirUserINI(self, get): |
| ''' |
| @name 设置防跨站 |
| ''' |
| get.id = get.get("id", None) |
| if not get.id: |
| return public.returnResult(status=False, msg="id不能为空!") |
|
|
| get.status = get.get("status", 0) |
| find_result = dp.sql("docker_sites").where("id=?", get.id).find() |
| if not find_result: |
| return public.returnResult(status=False, msg="未找到此ID【{}】的站点信息!".format(get.id)) |
|
|
| user_ini_file = os.path.join(find_result["path"], ".user.ini") |
| conf = public.readFile(user_ini_file) |
| if os.path.exists(user_ini_file): public.ExecShell("chattr -i " + user_ini_file) |
|
|
| if int(get.status) == 0: |
| if conf and "open_basedir" in conf: |
| rep = "\n*open_basedir.*" |
| conf = re.sub(rep, "", conf) |
| if not conf: |
| os.remove(user_ini_file) |
| else: |
| public.writeFile(user_ini_file, conf) |
| if os.path.exists(user_ini_file): public.ExecShell("chattr +i " + user_ini_file) |
| else: |
| if conf and "session.save_path" in conf: |
| rep = "session.save_path\s*=\s*(.*)" |
| s_path = re.search(rep, conf).groups(1)[0] |
| public.writeFile(user_ini_file, conf + '\nopen_basedir={}/:/tmp/:{}'.format(find_result["path"], s_path)) |
| else: |
| public.writeFile(user_ini_file, 'open_basedir={}/:/tmp/'.format(find_result["path"])) |
|
|
| if os.path.exists(user_ini_file): public.ExecShell("chattr +i " + user_ini_file) |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def reload_nginx_conf(self, get): |
| ''' |
| @name 刷新nginx_conf |
| ''' |
| get.siteName = get.get("siteName", None) |
|
|
| if get.siteName is None: |
| site_names = dp.sql("docker_sites").field("name").select() |
|
|
| reload_result = [] |
| for site_name in site_names: |
| get.site_name = site_name["name"] |
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| reload_result.append( |
| {"site_name": get.site_name, "status": False, "msg": "读取配置文件失败,请删除网站重新添加!"}) |
| continue |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| reload_result.append({"site_name": get.site_name, "status": False, "msg": update_result["msg"]}) |
| else: |
| get.site_name = get.siteName |
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
|
|
| public.serviceReload() |
| return public.returnResult(msg="设置网站目录成功") |
|
|
| |
| def get_php_project_info(self, get): |
| ''' |
| @name 获取指定网站的PHP信息 |
| ''' |
| get.id = get.get("id", None) |
| if not get.id: |
| return public.returnResult(status=False, msg="id不能为空!") |
|
|
| find_result = dp.sql("docker_sites").where("id=?", get.id).find() |
| if not find_result: |
| return public.returnResult(status=False, msg="未找到此ID【{}】的站点信息!".format(get.id)) |
|
|
| try: |
| service_info = json.loads(find_result["service_info"]) |
| except: |
| return public.returnResult(status=False, msg="ID【{}】站点的service_info读取失败,请重新添加网站再试!".format(get.id)) |
|
|
| php_name = service_info["name"].split(":")[0] |
| php_version = service_info["name"].split(":")[1] |
| php_project_info = { |
| "used": {"name": php_name, "version": php_version}, |
| } |
|
|
| |
| from mod.project.docker.runtime.runtimeManage import RuntimeManage |
| runtimeManage = RuntimeManage() |
| get.runtime_type = "php" |
| get.row = 20000 |
| php_runtime_list = runtimeManage.get_runtime_list(get) |
| if not php_runtime_list["status"]: return php_runtime_list |
|
|
| runtime_list = php_runtime_list["data"] |
| runtime_names = [] |
| for runtime in runtime_list: |
| if runtime["status"] != "normal": continue |
| runtime_names.append({"name": runtime["name"], "version": runtime["version"]}) |
|
|
| php_project_info["runtime_list"] = runtime_names |
|
|
| return public.returnResult(True, data=php_project_info) |
|
|
| |
| def switch_php_version(self, get): |
| ''' |
| @name 切换指定网站的PHP版本 |
| ''' |
| get.id = get.get("id", None) |
| if not get.id: |
| return public.returnResult(status=False, msg="id不能为空!") |
|
|
| get.runtime_name = get.get("runtime_name", None) |
| if not get.runtime_name: |
| return public.returnResult(status=False, msg="runtime_name不能为空!") |
|
|
| find_result = dp.sql("docker_sites").where("id=?", get.id).find() |
| if not find_result: |
| return public.returnResult(status=False, msg="未找到此ID【{}】的站点信息!".format(get.id)) |
|
|
| try: |
| service_info = json.loads(find_result["service_info"]) |
| except: |
| return public.returnResult(status=False, msg="ID【{}】站点的service_info读取失败,请重新添加网站再试!".format(get.id)) |
|
|
| service_info["name"] = get.runtime_name |
|
|
| dp.sql("docker_sites").where("id=?", get.id).update({"service_info": json.dumps(service_info)}) |
|
|
| |
| public.ExecShell("sed -i 's/^IMAGE_NAME=.*/IMAGE_NAME={}/' {}/.env".format(get.runtime_name, service_info["project_path"])) |
| public.ExecShell("docker-compose -f {}/docker-compose.yml down".format(service_info["project_path"])) |
| public.ExecShell("docker-compose -f {}/docker-compose.yml up -d".format(service_info["project_path"])) |
|
|
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|
| |
| def GetSiteDomains(self, get): |
| ''' |
| @name 获取指定网站的所有域名 |
| ''' |
| get.id = get.get("id", None) |
| if not get.id: |
| return public.returnResult(status=False, msg="id不能为空!") |
|
|
| data = {} |
| n_list = [] |
| from sslModel import dataModel |
| get.docker_site_id = get.id |
| dns_data = dataModel.main().get_domain_dns_config(get) |
| for domain in dns_data: |
| tmp = {'id': domain['domain_id'], 'name': domain['name'], 'binding': False, 'apply_ssl': 1, 'dns_status': domain['status'], 'root_domain_id': domain['domain_id']} |
| if public.checkIp(domain['name']): tmp['apply_ssl'] = 0 |
| n_list.append(tmp) |
|
|
| data['domains'] = n_list |
|
|
| return data |
|
|
| def get_domian_dns_dic(self): |
| try: |
| from sslModel import dataModel |
| data = dataModel.main().get_domain_dns_config(public.dict_obj()) |
| return {i["name"]: {"dns_status": i["status"], "root_domain_id": i["domain_id"]} for i in data} |
| except: |
| return {} |
|
|
| |
| def set_cert_to_site(self, get): |
| ''' |
| @name |
| ''' |
| from mod.project.docker.sites.sslManage import Acme_V2 |
| acme = Acme_V2() |
| exclude_data = acme.get_exclude_hash(get) |
| ssl_hash = exclude_data['exclude_hash_let'].get(get.index) |
| if not ssl_hash: |
| return public.returnResult(False, "未找到此证书") |
| get.ssl_hash = ssl_hash |
|
|
| from mod.project.docker.sites.sslManage import SslManage |
| ssl_manage = SslManage() |
| return ssl_manage.SetCertToSite(get) |
|
|
| |
| def set_proxy_buffering(self, get): |
| ''' |
| @name 设置proxy_buffering状态 |
| ''' |
| get.site_name = get.get("site_name", None) |
| if not get.site_name: |
| return public.returnResult(status=False, msg="site_name不能为空!") |
|
|
| get.status = get.get("status", 0) |
| get.proxy_path = get.get("proxy_path", None) |
| if not get.proxy_path: |
| return public.returnResult(status=False, msg="proxy_path不能为空!") |
|
|
| get.proxy_json_conf = self.read_json_conf(get) |
| if not get.proxy_json_conf: |
| return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") |
|
|
| for proxy_info in get.proxy_json_conf["proxy_info"]: |
| if not "proxy_pass" in proxy_info: continue |
| if not proxy_info["proxy_pass"]: continue |
|
|
| if get.proxy_path == proxy_info["proxy_path"]: |
| print(get.proxy_path) |
| print(proxy_info["proxy_path"]) |
| if int(get.status) == 1: |
| proxy_info["proxy_buffering"] = True |
| else: |
| proxy_info["proxy_buffering"] = False |
| break |
|
|
| update_result = self.update_nginx_conf(get) |
| if not update_result["status"]: |
| return public.returnResult(status=False, msg=update_result["msg"]) |
| public.serviceReload() |
|
|
| return public.returnResult(msg="设置成功!") |
|
|