Kaynağa Gözat

feat: 方便对接第三方cookie

tuonian 1 yıl önce
ebeveyn
işleme
7d8ebee4c4

+ 21 - 11
server/conf/app.conf

@@ -1,11 +1,21 @@
-appname = server
-httpport = 8080
-runmode = dev
-copyrequestbody = true
-
-baseApi = /nginx-ui/api
-
-datadir = ./data
-dbdir = ./data/db
-nginxPath = /usr/sbin/nginx
-nginxDir = /etc/nginx
+appname = server
+httpport = 8080
+runmode = dev
+copyrequestbody = true
+
+baseApi = /nginx-ui/api
+
+datadir = ./data
+dbdir = ./data/db
+nginxPath = /usr/sbin/nginx
+nginxDir = /etc/nginx
+
+sessionon = true
+sessionprovider = file
+sessionname = nginx_session
+sessiongcmaxlifetime = 7200
+sessionproviderconfig = "./data/sessions"
+
+thirdsessionenable = true
+thirdsessionname = tq.session
+thirdsessioncheckurl = http://10.10.0.1:20003/session/check

+ 40 - 40
server/config/config.go

@@ -1,40 +1,40 @@
-package config
-
-import (
-	"github.com/astaxie/beego"
-	"github.com/astaxie/beego/logs"
-	"os"
-	"server/utils"
-)
-
-type AppConfig struct {
-	BaseApi string
-	DataDir string
-}
-
-var Config = &AppConfig{}
-
-func GetDataDir() string {
-	return Config.DataDir
-}
-
-func init() {
-	// 需要和前端配置好
-	baseApi := beego.AppConfig.String("baseApi")
-	if baseApi == "" {
-		baseApi = "/ngx"
-		err := beego.AppConfig.Set("baseApi", baseApi)
-		if err != nil {
-			logs.Info("init set baseApi", err)
-		}
-	}
-	Config.BaseApi = baseApi
-	Config.DataDir = beego.AppConfig.String("datadir")
-	if exist := utils.IsExist(Config.DataDir); exist == false {
-		err := os.MkdirAll(Config.DataDir, 0777)
-		logs.Warn("create data dir fail", err)
-		if err != nil {
-			panic(err)
-		}
-	}
-}
+package config
+
+import (
+	"github.com/astaxie/beego"
+	"github.com/astaxie/beego/logs"
+	"os"
+	"server/utils"
+)
+
+type AppConfig struct {
+	BaseApi string
+	DataDir string
+}
+
+var Config = &AppConfig{}
+
+func GetDataDir() string {
+	return Config.DataDir
+}
+
+func init() {
+	// 需要和前端配置好
+	baseApi := beego.AppConfig.String("baseApi")
+	if baseApi == "" {
+		baseApi = "/ngx"
+		err := beego.AppConfig.Set("baseApi", baseApi)
+		if err != nil {
+			logs.Info("init set baseApi", err)
+		}
+	}
+	Config.BaseApi = baseApi
+	Config.DataDir = beego.AppConfig.String("datadir")
+	if exist := utils.IsExist(Config.DataDir); exist == false {
+		err := os.MkdirAll(Config.DataDir, 0777)
+		logs.Warn("create data dir fail", err)
+		if err != nil {
+			panic(err)
+		}
+	}
+}

+ 203 - 203
server/controllers/certificate.go

@@ -1,203 +1,203 @@
-package controllers
-
-import (
-	"encoding/json"
-	"errors"
-	"fmt"
-	"github.com/astaxie/beego/logs"
-	"github.com/astaxie/beego/orm"
-	"server/models"
-	nginx2 "server/nginx"
-	"server/utils"
-	"strconv"
-	"strings"
-	"time"
-)
-
-type CertController struct {
-	BaseController
-}
-
-// 这个是根据域名的名称来的,自定义命令,即文件名称
-func saveOrUpdate(cert *models.NginxCerts) error {
-	o := orm.NewOrm()
-	find := models.NginxCerts{ServiceName: cert.ServiceName, NginxId: cert.NginxId}
-	err := o.Read(&find, "service_name", "nginx_id")
-	if err != nil && err != orm.ErrNoRows {
-		return err
-	}
-	if err == orm.ErrNoRows {
-		_, err := o.Insert(cert)
-		return err
-	}
-	_, err = o.Update(cert)
-	return err
-}
-
-func (c *CertController) getNginx() *models.Nginx {
-	idStr := c.getParam(":id")
-	id, err := strconv.Atoi(idStr)
-	logs.Info("id", id)
-	if err != nil {
-		c.ErrorJson(err)
-		return nil
-	}
-	var nginx = models.Nginx{
-		Id: id,
-	}
-	o := orm.NewOrm()
-	err = o.Read(&nginx)
-	if err != nil {
-		c.ErrorJson(err)
-		return nil
-	}
-	if nginx.DataDir == "" {
-		c.setCode(-1).setMsg("请先配置数据目录位置!").json()
-		return nil
-	}
-	return &nginx
-}
-
-// Get getAll
-func (c *CertController) Get() {
-	nginx := c.getNginx()
-	if nginx == nil {
-		return
-	}
-	o := orm.NewOrm()
-	var list []models.NginxCerts
-	_, err := o.QueryTable((*models.NginxCerts)(nil)).Filter("NginxId", nginx.Id).All(&list)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	c.setData(list).json()
-}
-
-// Sync 从配置的证书路径同步证书到数据库
-func (c *CertController) Sync() {
-	nginx := c.getNginx()
-	if nginx == nil {
-		return
-	}
-	ins := nginx2.GetInstance(nginx)
-	names := strings.Split(ins.GetCerts(), "\n")
-	var certs []models.NginxCerts
-	for i := range names {
-		name := names[i]
-		if strings.HasSuffix(name, ".key") {
-			serviceName := name[0 : len(name)-4]
-			cert, err := ins.GetCertData(serviceName)
-			cert.NginxId = nginx.Id
-			cert.CreatedAt = time.Now().Format("2006-02-01 15:04")
-			if err != nil {
-				logs.Warn("getCertData fail", err, serviceName)
-			} else {
-				err = saveOrUpdate(cert)
-				if err != nil {
-					logs.Warn("save certs fail", err, serviceName)
-				} else {
-					certs = append(certs, *cert)
-				}
-			}
-		}
-	}
-	c.setData(true).json()
-}
-
-// Post save certs
-func (c *CertController) Post() {
-	nginx := c.getNginx()
-	if nginx == nil {
-		return
-	}
-	var cert models.NginxCerts
-	err := json.Unmarshal(c.Ctx.Input.RequestBody, &cert)
-	if err != nil {
-		logs.Error(err, string(c.Ctx.Input.RequestBody))
-		c.ErrorJson(err)
-		return
-	}
-	if cert.Pem == "" || cert.Key == "" {
-		c.setCode(-1).setMsg("请输入证书私钥和公钥内容!").json()
-		return
-	}
-
-	parse, err := utils.CheckHttps(cert.Pem)
-	if err != nil {
-		cert.HintMsg = fmt.Sprintf("证书公钥解析异常:%s", err.Error())
-	} else {
-		cert.ExpiresAt = parse.NotAfter.Format("2006-01-02 15:04")
-		cert.SubjectName = parse.Subject.CommonName
-	}
-	logs.Info("parse", cert.SubjectName)
-	o := orm.NewOrm()
-	cert.NginxId = nginx.Id
-	if cert.Id > 0 {
-		_, err = o.Update(&cert)
-	} else {
-		cert.CreatedAt = time.Now().Format("2006-01-02 15:04")
-		_, err = o.Insert(&cert)
-	}
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	ins := nginx2.GetInstance(nginx)
-	err = ins.SaveCerts(&cert)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	c.json()
-}
-
-// Delete del certs
-func (c *CertController) Delete() {
-	nginx := c.getNginx()
-	if nginx == nil {
-		return
-	}
-	ins := nginx2.GetInstance(nginx)
-	certId, err := c.GetInt("id", -1)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	if certId < 0 {
-		c.ErrorJson(errors.New("参数错误"))
-		return
-	}
-
-	dirs := ins.CheckDirs()
-	if dirs.CertsDir == "" || dirs.CertsDir == "/" {
-		c.setCode(-1).setMsg("请先配置证书路径,不能为根路径。")
-		c.json()
-		return
-	}
-	o := orm.NewOrm()
-	cert := models.NginxCerts{Id: certId, NginxId: nginx.Id}
-	err = o.Read(&cert, "id", "nginx_id")
-	if err != nil && err != orm.ErrNoRows {
-		c.ErrorJson(err)
-		return
-	} else if err != nil && err == orm.ErrNoRows {
-		c.json()
-		return
-	}
-
-	_, err = o.Delete(&cert)
-	if err != nil && err != orm.ErrNoRows {
-		c.ErrorJson(err)
-		return
-	}
-	certName := cert.ServiceName
-	cmd1 := fmt.Sprintf("cd %s && if [ -f %s.key ];then mv -f %s.key %s;fi", dirs.CertsDir, certName, certName, dirs.BackupDir)
-	cmd2 := fmt.Sprintf("cd %s && if [ -f %s.pem ];then mv -f %s.pem %s;fi", dirs.CertsDir, certName, certName, dirs.BackupDir)
-	resp, err := ins.Run(fmt.Sprintf("%s;%s", cmd1, cmd2))
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	c.setData(resp).json()
-}
+package controllers
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"github.com/astaxie/beego/logs"
+	"github.com/astaxie/beego/orm"
+	"server/models"
+	nginx2 "server/nginx"
+	"server/utils"
+	"strconv"
+	"strings"
+	"time"
+)
+
+type CertController struct {
+	BaseController
+}
+
+// 这个是根据域名的名称来的,自定义命令,即文件名称
+func saveOrUpdate(cert *models.NginxCerts) error {
+	o := orm.NewOrm()
+	find := models.NginxCerts{ServiceName: cert.ServiceName, NginxId: cert.NginxId}
+	err := o.Read(&find, "service_name", "nginx_id")
+	if err != nil && err != orm.ErrNoRows {
+		return err
+	}
+	if err == orm.ErrNoRows {
+		_, err := o.Insert(cert)
+		return err
+	}
+	_, err = o.Update(cert)
+	return err
+}
+
+func (c *CertController) getNginx() *models.Nginx {
+	idStr := c.getParam(":id")
+	id, err := strconv.Atoi(idStr)
+	logs.Info("id", id)
+	if err != nil {
+		c.ErrorJson(err)
+		return nil
+	}
+	var nginx = models.Nginx{
+		Id: id,
+	}
+	o := orm.NewOrm()
+	err = o.Read(&nginx)
+	if err != nil {
+		c.ErrorJson(err)
+		return nil
+	}
+	if nginx.DataDir == "" {
+		c.setCode(-1).setMsg("请先配置数据目录位置!").json()
+		return nil
+	}
+	return &nginx
+}
+
+// Get getAll
+func (c *CertController) Get() {
+	nginx := c.getNginx()
+	if nginx == nil {
+		return
+	}
+	o := orm.NewOrm()
+	var list []models.NginxCerts
+	_, err := o.QueryTable((*models.NginxCerts)(nil)).Filter("NginxId", nginx.Id).All(&list)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	c.setData(list).json()
+}
+
+// Sync 从配置的证书路径同步证书到数据库
+func (c *CertController) Sync() {
+	nginx := c.getNginx()
+	if nginx == nil {
+		return
+	}
+	ins := nginx2.GetInstance(nginx)
+	names := strings.Split(ins.GetCerts(), "\n")
+	var certs []models.NginxCerts
+	for i := range names {
+		name := names[i]
+		if strings.HasSuffix(name, ".key") {
+			serviceName := name[0 : len(name)-4]
+			cert, err := ins.GetCertData(serviceName)
+			cert.NginxId = nginx.Id
+			cert.CreatedAt = time.Now().Format("2006-02-01 15:04")
+			if err != nil {
+				logs.Warn("getCertData fail", err, serviceName)
+			} else {
+				err = saveOrUpdate(cert)
+				if err != nil {
+					logs.Warn("save certs fail", err, serviceName)
+				} else {
+					certs = append(certs, *cert)
+				}
+			}
+		}
+	}
+	c.setData(true).json()
+}
+
+// Post save certs
+func (c *CertController) Post() {
+	nginx := c.getNginx()
+	if nginx == nil {
+		return
+	}
+	var cert models.NginxCerts
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &cert)
+	if err != nil {
+		logs.Error(err, string(c.Ctx.Input.RequestBody))
+		c.ErrorJson(err)
+		return
+	}
+	if cert.Pem == "" || cert.Key == "" {
+		c.setCode(-1).setMsg("请输入证书私钥和公钥内容!").json()
+		return
+	}
+
+	parse, err := utils.CheckHttps(cert.Pem)
+	if err != nil {
+		cert.HintMsg = fmt.Sprintf("证书公钥解析异常:%s", err.Error())
+	} else {
+		cert.ExpiresAt = parse.NotAfter.Format("2006-01-02 15:04")
+		cert.SubjectName = parse.Subject.CommonName
+	}
+	logs.Info("parse", cert.SubjectName)
+	o := orm.NewOrm()
+	cert.NginxId = nginx.Id
+	if cert.Id > 0 {
+		_, err = o.Update(&cert)
+	} else {
+		cert.CreatedAt = time.Now().Format("2006-01-02 15:04")
+		_, err = o.Insert(&cert)
+	}
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	ins := nginx2.GetInstance(nginx)
+	err = ins.SaveCerts(&cert)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	c.json()
+}
+
+// Delete del certs
+func (c *CertController) Delete() {
+	nginx := c.getNginx()
+	if nginx == nil {
+		return
+	}
+	ins := nginx2.GetInstance(nginx)
+	certId, err := c.GetInt("id", -1)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	if certId < 0 {
+		c.ErrorJson(errors.New("参数错误"))
+		return
+	}
+
+	dirs := ins.CheckDirs()
+	if dirs.CertsDir == "" || dirs.CertsDir == "/" {
+		c.setCode(-1).setMsg("请先配置证书路径,不能为根路径。")
+		c.json()
+		return
+	}
+	o := orm.NewOrm()
+	cert := models.NginxCerts{Id: certId, NginxId: nginx.Id}
+	err = o.Read(&cert, "id", "nginx_id")
+	if err != nil && err != orm.ErrNoRows {
+		c.ErrorJson(err)
+		return
+	} else if err != nil && err == orm.ErrNoRows {
+		c.json()
+		return
+	}
+
+	_, err = o.Delete(&cert)
+	if err != nil && err != orm.ErrNoRows {
+		c.ErrorJson(err)
+		return
+	}
+	certName := cert.ServiceName
+	cmd1 := fmt.Sprintf("cd %s && if [ -f %s.key ];then mv -f %s.key %s;fi", dirs.CertsDir, certName, certName, dirs.BackupDir)
+	cmd2 := fmt.Sprintf("cd %s && if [ -f %s.pem ];then mv -f %s.pem %s;fi", dirs.CertsDir, certName, certName, dirs.BackupDir)
+	resp, err := ins.Run(fmt.Sprintf("%s;%s", cmd1, cmd2))
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	c.setData(resp).json()
+}

+ 29 - 29
server/controllers/config.go

@@ -1,29 +1,29 @@
-package controllers
-
-import (
-	"fmt"
-	"github.com/astaxie/beego/logs"
-	config2 "server/config"
-)
-
-type ConfigController struct {
-	BaseController
-}
-
-// Get 前端的配置文件
-func (c *ConfigController) Get() {
-
-	config := config2.Config
-
-	js := fmt.Sprintf("  window.CONFIG = {\n        baseApi: '%s'\n    }", config.BaseApi)
-	output := c.Ctx.Output
-
-	output.SetStatus(200)
-	output.Header("Cache-Control", "no-cache")
-	output.Header("content-type", "text/javascript")
-	err := c.Ctx.Output.Body([]byte(js))
-	if err != nil {
-		logs.Error("config.js fail", err)
-		return
-	}
-}
+package controllers
+
+import (
+	"fmt"
+	"github.com/astaxie/beego/logs"
+	config2 "server/config"
+)
+
+type ConfigController struct {
+	BaseController
+}
+
+// Get 前端的配置文件
+func (c *ConfigController) Get() {
+
+	config := config2.Config
+
+	js := fmt.Sprintf("  window.CONFIG = {\n        baseApi: '%s'\n    }", config.BaseApi)
+	output := c.Ctx.Output
+
+	output.SetStatus(200)
+	output.Header("Cache-Control", "no-cache")
+	output.Header("content-type", "text/javascript")
+	err := c.Ctx.Output.Body([]byte(js))
+	if err != nil {
+		logs.Error("config.js fail", err)
+		return
+	}
+}

+ 85 - 85
server/controllers/default.go

@@ -1,85 +1,85 @@
-package controllers
-
-import (
-	"github.com/astaxie/beego"
-	"github.com/astaxie/beego/logs"
-	"strconv"
-)
-
-type RespData struct {
-	Code int         `json:"code"`
-	Msg  string      `json:"msg"`
-	Data interface{} `json:"data"`
-}
-
-type BaseController struct {
-	beego.Controller
-	jsonData *RespData
-	// json real data
-	respData map[string]any
-}
-
-func (c *BaseController) json() {
-	c.checkJsonData()
-	if c.respData != nil {
-		c.jsonData.Data = c.respData
-	}
-	c.Data["json"] = c.jsonData
-	c.ServeJSON()
-}
-
-func (c *BaseController) ErrorJson(error error) {
-	c.setCode(-1).setMsg(error.Error()).json()
-}
-
-func (c *BaseController) checkJsonData() *BaseController {
-	data := c.jsonData
-	if data == nil {
-		data = &RespData{
-			Code: 0,
-			Msg:  "success",
-			Data: nil,
-		}
-		c.jsonData = data
-	}
-	return c
-}
-
-func (c *BaseController) setData(v interface{}) *BaseController {
-	c.checkJsonData()
-	c.jsonData.Data = v
-	return c
-}
-
-func (c *BaseController) addRespData(k string, v interface{}) *BaseController {
-	c.checkJsonData()
-	if c.respData == nil {
-		c.respData = map[string]any{}
-	}
-	c.respData[k] = v
-	return c
-}
-
-func (c *BaseController) setCode(code int) *BaseController {
-	c.checkJsonData()
-	c.jsonData.Code = code
-	return c
-}
-func (c *BaseController) setMsg(msg string) *BaseController {
-	c.checkJsonData()
-	c.jsonData.Msg = msg
-	return c
-}
-
-func (c *BaseController) getParam(k string) string {
-	return c.Ctx.Input.Param(k)
-}
-func (c *BaseController) getIntParam(k string) (int, error) {
-	idStr := c.Ctx.Input.Param(k)
-	id, err := strconv.Atoi(idStr)
-	logs.Info("id", id)
-	if err != nil {
-		return 0, err
-	}
-	return id, nil
-}
+package controllers
+
+import (
+	"github.com/astaxie/beego"
+	"github.com/astaxie/beego/logs"
+	"strconv"
+)
+
+type RespData struct {
+	Code int         `json:"code"`
+	Msg  string      `json:"msg"`
+	Data interface{} `json:"data"`
+}
+
+type BaseController struct {
+	beego.Controller
+	jsonData *RespData
+	// json real data
+	respData map[string]any
+}
+
+func (c *BaseController) json() {
+	c.checkJsonData()
+	if c.respData != nil {
+		c.jsonData.Data = c.respData
+	}
+	c.Data["json"] = c.jsonData
+	c.ServeJSON()
+}
+
+func (c *BaseController) ErrorJson(error error) {
+	c.setCode(-1).setMsg(error.Error()).json()
+}
+
+func (c *BaseController) checkJsonData() *BaseController {
+	data := c.jsonData
+	if data == nil {
+		data = &RespData{
+			Code: 0,
+			Msg:  "success",
+			Data: nil,
+		}
+		c.jsonData = data
+	}
+	return c
+}
+
+func (c *BaseController) setData(v interface{}) *BaseController {
+	c.checkJsonData()
+	c.jsonData.Data = v
+	return c
+}
+
+func (c *BaseController) addRespData(k string, v interface{}) *BaseController {
+	c.checkJsonData()
+	if c.respData == nil {
+		c.respData = map[string]any{}
+	}
+	c.respData[k] = v
+	return c
+}
+
+func (c *BaseController) setCode(code int) *BaseController {
+	c.checkJsonData()
+	c.jsonData.Code = code
+	return c
+}
+func (c *BaseController) setMsg(msg string) *BaseController {
+	c.checkJsonData()
+	c.jsonData.Msg = msg
+	return c
+}
+
+func (c *BaseController) getParam(k string) string {
+	return c.Ctx.Input.Param(k)
+}
+func (c *BaseController) getIntParam(k string) (int, error) {
+	idStr := c.Ctx.Input.Param(k)
+	id, err := strconv.Atoi(idStr)
+	logs.Info("id", id)
+	if err != nil {
+		return 0, err
+	}
+	return id, nil
+}

+ 173 - 173
server/controllers/file.go

@@ -1,173 +1,173 @@
-package controllers
-
-import (
-	"encoding/json"
-	"errors"
-	"fmt"
-	"github.com/astaxie/beego/logs"
-	"github.com/astaxie/beego/orm"
-	"os"
-	config2 "server/config"
-	"server/models"
-	nginx2 "server/nginx"
-	"server/utils"
-	"strings"
-	"time"
-)
-
-type FileController struct {
-	BaseController
-}
-
-func getRootDir() (string, error) {
-	root := fmt.Sprintf("%s/files", config2.GetDataDir())
-	if exist := utils.IsExist(root); exist != true {
-		err := os.MkdirAll(root, 0777)
-		if err != nil {
-			return "", err
-		}
-	}
-	return root, nil
-}
-
-// Get getAll
-func (c *FileController) Get() {
-	fileName := c.GetString("filename")
-	logs.Info("get file: {}", fileName)
-	root, err := getRootDir()
-	if err != nil {
-		c.Ctx.Output.SetStatus(404)
-		return
-	}
-
-	fromFile := fmt.Sprintf("%s/%s", root, fileName)
-	c.Ctx.Output.Download(fromFile, fileName)
-}
-
-// Post save certs
-func (c *FileController) Post() {
-	f, header, err := c.GetFile("file")
-	if err != nil {
-		c.Ctx.Output.SetStatus(500)
-		c.ErrorJson(err)
-		return
-	}
-
-	var req models.FileReq
-	err = c.ParseForm(&req)
-	if err != nil {
-		c.Ctx.Output.SetStatus(500)
-		c.ErrorJson(err)
-		return
-	}
-
-	defer f.Close()
-	root, err := getRootDir()
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	if strings.HasPrefix(req.Path, "/") {
-		req.Path = req.Path[1:len(req.Path)]
-	}
-	root = fmt.Sprintf("%s/%s", root, req.Key)
-	index := strings.LastIndex(req.Path, "/")
-	if index > 0 {
-		subDir := req.Path[0:index]
-		root = fmt.Sprintf("%s/%s", root, subDir)
-	}
-	if !utils.IsExist(root) {
-		err = os.MkdirAll(root, 0777)
-	}
-	if err != nil {
-		c.Ctx.Output.SetStatus(500)
-		c.ErrorJson(err)
-		return
-	}
-
-	toFile := fmt.Sprintf("%s/%s", root, header.Filename)
-	err = c.SaveToFile("file", toFile)
-	if err != nil {
-		c.Ctx.Output.SetStatus(500)
-		c.ErrorJson(err)
-		return
-	}
-	c.setData(toFile).json()
-}
-
-// Deploy 部署到服务器
-func (c *FileController) Deploy() {
-	var req models.DeployReq
-	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
-	if err != nil {
-		logs.Error(err, string(c.Ctx.Input.RequestBody))
-		c.ErrorJson(err)
-		return
-	}
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	err = HandleDeploy(req)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	c.json()
-}
-
-func HandleDeploy(req models.DeployReq) error {
-	root, err := getRootDir()
-	if err != nil {
-		return err
-	}
-	root = fmt.Sprintf("%s/%s", root, req.Key)
-	if !utils.IsExist(root) {
-		logs.Warn("dir not exist: ", root)
-		return errors.New("未上传文件或者文件已被删除!")
-	}
-	o := orm.NewOrm()
-	nginx := models.Nginx{
-		Id: req.NginxId,
-	}
-	err = o.Read(&nginx)
-	if err != nil {
-		return err
-	}
-	ins := nginx2.GetInstance(&nginx)
-	dirs := ins.CheckDirs()
-	if nginx.IsLocal {
-		cmd := fmt.Sprintf("if [ ! -d %s ];then mkdir -p %s;fi && cp -r %s/* %s", req.Dir, req.Dir, root, req.Dir)
-		_, err := ins.Run(cmd)
-		return err
-	}
-
-	tarPath := fmt.Sprintf("%s.tar.gz", root)
-	if !utils.IsExist(tarPath) {
-		err = utils.TarXz(tarPath, root)
-		if err != nil {
-			return err
-		}
-	}
-
-	timeNow := time.Now().Format("20060102150105")
-	dst := fmt.Sprintf("%s/%s_%s.tar.gz", dirs.BackupDir, req.Key, timeNow)
-	err = ins.SendFile(tarPath, dst)
-	if err != nil {
-		return err
-	}
-	cmd := fmt.Sprintf("if [ ! -d %s ];then mkdir -p %s;fi && tar -zxvf %s -C %s", req.Dir, req.Dir, dst, req.Dir)
-	if req.Clear {
-		cmd = fmt.Sprintf("rm -rf %s;%s", req.Dir, cmd)
-	}
-	_, err = ins.Run(cmd)
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-// Delete del certs
-func (c *FileController) Delete() {
-
-}
+package controllers
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"github.com/astaxie/beego/logs"
+	"github.com/astaxie/beego/orm"
+	"os"
+	config2 "server/config"
+	"server/models"
+	nginx2 "server/nginx"
+	"server/utils"
+	"strings"
+	"time"
+)
+
+type FileController struct {
+	BaseController
+}
+
+func getRootDir() (string, error) {
+	root := fmt.Sprintf("%s/files", config2.GetDataDir())
+	if exist := utils.IsExist(root); exist != true {
+		err := os.MkdirAll(root, 0777)
+		if err != nil {
+			return "", err
+		}
+	}
+	return root, nil
+}
+
+// Get getAll
+func (c *FileController) Get() {
+	fileName := c.GetString("filename")
+	logs.Info("get file: {}", fileName)
+	root, err := getRootDir()
+	if err != nil {
+		c.Ctx.Output.SetStatus(404)
+		return
+	}
+
+	fromFile := fmt.Sprintf("%s/%s", root, fileName)
+	c.Ctx.Output.Download(fromFile, fileName)
+}
+
+// Post save certs
+func (c *FileController) Post() {
+	f, header, err := c.GetFile("file")
+	if err != nil {
+		c.Ctx.Output.SetStatus(500)
+		c.ErrorJson(err)
+		return
+	}
+
+	var req models.FileReq
+	err = c.ParseForm(&req)
+	if err != nil {
+		c.Ctx.Output.SetStatus(500)
+		c.ErrorJson(err)
+		return
+	}
+
+	defer f.Close()
+	root, err := getRootDir()
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	if strings.HasPrefix(req.Path, "/") {
+		req.Path = req.Path[1:len(req.Path)]
+	}
+	root = fmt.Sprintf("%s/%s", root, req.Key)
+	index := strings.LastIndex(req.Path, "/")
+	if index > 0 {
+		subDir := req.Path[0:index]
+		root = fmt.Sprintf("%s/%s", root, subDir)
+	}
+	if !utils.IsExist(root) {
+		err = os.MkdirAll(root, 0777)
+	}
+	if err != nil {
+		c.Ctx.Output.SetStatus(500)
+		c.ErrorJson(err)
+		return
+	}
+
+	toFile := fmt.Sprintf("%s/%s", root, header.Filename)
+	err = c.SaveToFile("file", toFile)
+	if err != nil {
+		c.Ctx.Output.SetStatus(500)
+		c.ErrorJson(err)
+		return
+	}
+	c.setData(toFile).json()
+}
+
+// Deploy 部署到服务器
+func (c *FileController) Deploy() {
+	var req models.DeployReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		logs.Error(err, string(c.Ctx.Input.RequestBody))
+		c.ErrorJson(err)
+		return
+	}
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	err = HandleDeploy(req)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	c.json()
+}
+
+func HandleDeploy(req models.DeployReq) error {
+	root, err := getRootDir()
+	if err != nil {
+		return err
+	}
+	root = fmt.Sprintf("%s/%s", root, req.Key)
+	if !utils.IsExist(root) {
+		logs.Warn("dir not exist: ", root)
+		return errors.New("未上传文件或者文件已被删除!")
+	}
+	o := orm.NewOrm()
+	nginx := models.Nginx{
+		Id: req.NginxId,
+	}
+	err = o.Read(&nginx)
+	if err != nil {
+		return err
+	}
+	ins := nginx2.GetInstance(&nginx)
+	dirs := ins.CheckDirs()
+	if nginx.IsLocal {
+		cmd := fmt.Sprintf("if [ ! -d %s ];then mkdir -p %s;fi && cp -r %s/* %s", req.Dir, req.Dir, root, req.Dir)
+		_, err := ins.Run(cmd)
+		return err
+	}
+
+	tarPath := fmt.Sprintf("%s.tar.gz", root)
+	if !utils.IsExist(tarPath) {
+		err = utils.TarXz(tarPath, root)
+		if err != nil {
+			return err
+		}
+	}
+
+	timeNow := time.Now().Format("20060102150105")
+	dst := fmt.Sprintf("%s/%s_%s.tar.gz", dirs.BackupDir, req.Key, timeNow)
+	err = ins.SendFile(tarPath, dst)
+	if err != nil {
+		return err
+	}
+	cmd := fmt.Sprintf("if [ ! -d %s ];then mkdir -p %s;fi && tar -zxvf %s -C %s", req.Dir, req.Dir, dst, req.Dir)
+	if req.Clear {
+		cmd = fmt.Sprintf("rm -rf %s;%s", req.Dir, cmd)
+	}
+	_, err = ins.Run(cmd)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+// Delete del certs
+func (c *FileController) Delete() {
+
+}

+ 250 - 250
server/controllers/nginx.go

@@ -1,250 +1,250 @@
-package controllers
-
-import (
-	"encoding/json"
-	"github.com/astaxie/beego/logs"
-	"github.com/astaxie/beego/orm"
-	"server/models"
-	ngx "server/nginx"
-	"strconv"
-)
-
-type NginxController struct {
-	BaseController
-}
-
-const ReplacePassword = "******"
-
-// Get getAll
-func (c *NginxController) Get() {
-	o := orm.NewOrm()
-	qs := o.QueryTable("nginx")
-	var list []*models.Nginx
-	_, err := qs.All(&list)
-	for i := range list {
-		item := list[i]
-		if item.Password != "" {
-			item.Password = ReplacePassword
-		}
-	}
-
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	} else {
-		c.setData(list).json()
-	}
-}
-
-// Post add nginx instance
-func (c *NginxController) Post() {
-	var nginx models.Nginx
-	err := json.Unmarshal(c.Ctx.Input.RequestBody, &nginx)
-	if err != nil {
-		logs.Error(err, string(c.Ctx.Input.RequestBody))
-		c.ErrorJson(err)
-		return
-	}
-	nginx.Check()
-	o := orm.NewOrm()
-	var saveErr error
-	if nginx.Id == 0 {
-		_, err = o.Insert(&nginx)
-		saveErr = err
-	} else {
-		tmp := models.Nginx{
-			Id: nginx.Id,
-		}
-		err = o.Read(&tmp)
-		if err != nil {
-			c.ErrorJson(err)
-			return
-		}
-		if nginx.Password == ReplacePassword {
-			nginx.Password = tmp.Password
-		}
-		nginx.HttpConf = tmp.HttpConf
-		_, err = o.Update(&nginx)
-		saveErr = err
-	}
-
-	if saveErr != nil {
-		c.ErrorJson(saveErr)
-		return
-	}
-	logs.Info("post", nginx)
-
-	instance := ngx.GetInstance(&nginx)
-	err = instance.Connect()
-	if err != nil {
-		c.setCode(1).setMsg(err.Error()).setData(nginx)
-		c.json()
-		return
-	}
-	out, err := instance.GetVersion()
-	if err != nil {
-		c.setCode(1).setMsg(err.Error()).setData(nginx)
-		c.json()
-		return
-	}
-	nginx.VersionInfo = out
-	_, _ = o.Update(&nginx, "VersionInfo")
-	c.setData(nginx).json()
-}
-
-// StartNginx startNginx
-func (c *NginxController) StartNginx() {
-	idStr := c.getParam(":id")
-	id, err := strconv.Atoi(idStr)
-	logs.Info("id", id)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	var nginx = models.Nginx{
-		Id: id,
-	}
-	o := orm.NewOrm()
-	err = o.Read(&nginx)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	instance := ngx.GetInstance(&nginx)
-	err = instance.Start()
-	isRun, msg := instance.Status()
-	c.setData(isRun).setMsg(msg).json()
-}
-
-// StopNginx add nginx instance
-func (c *NginxController) StopNginx() {
-	idStr := c.getParam(":id")
-	id, err := strconv.Atoi(idStr)
-	logs.Info("id", id)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-
-	var nginx = models.Nginx{
-		Id: id,
-	}
-	o := orm.NewOrm()
-	err = o.Read(&nginx)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	instance := ngx.GetInstance(&nginx)
-	err = instance.Stop()
-	isRun, msg := instance.Status()
-	c.setData(isRun).setMsg(msg).json()
-}
-
-// RefreshHttp nginx detail data
-func (c *NginxController) RefreshHttp() {
-	var nginx models.Nginx
-	err := json.Unmarshal(c.Ctx.Input.RequestBody, &nginx)
-	if err != nil {
-		logs.Error(err, string(c.Ctx.Input.RequestBody))
-		c.ErrorJson(err)
-		return
-	}
-
-	logs.Info("id", nginx)
-
-	o := orm.NewOrm()
-	if nginx.HttpConf != "" {
-		_, err = o.Update(&nginx, "HttpConf","HttpData")
-		if err != nil {
-			c.ErrorJson(err)
-			return
-		}
-	}
-	err = o.Read(&nginx)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	ins := ngx.GetInstance(&nginx)
-	err = ins.RefreshHttp(nginx)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	c.setData(nginx)
-	c.json()
-}
-
-// GetNginx nginx detail data
-func (c *NginxController) GetNginx() {
-	idStr := c.getParam(":id")
-	id, err := strconv.Atoi(idStr)
-	logs.Info("id", id)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	o := orm.NewOrm()
-
-	var nginx = models.Nginx{Id: id}
-	err = o.Read(&nginx)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	if nginx.Password != "" {
-		nginx.Password = ReplacePassword
-	}
-	c.addRespData("nginx", nginx)
-
-	var servers []models.ServerHost
-	_, err = o.QueryTable((*models.ServerHost)(nil)).Filter("NginxId", id).All(&servers)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	c.addRespData("servers", servers)
-	c.json()
-}
-
-// DelNginx delete a instance
-func (c *NginxController) DelNginx() {
-	id, err := c.getIntParam(":id")
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	o := orm.NewOrm()
-	nginx := models.Nginx{Id: id}
-	count, err := o.Delete(&nginx)
-	if err != nil {
-		c.ErrorJson(err)
-	} else {
-		c.setData(count).json()
-	}
-}
-
-// StopNginx add nginx instance
-func (c *NginxController) StatusNginx() {
-	idStr := c.getParam(":id")
-	id, err := strconv.Atoi(idStr)
-	logs.Info("id", id)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-
-	var nginx = models.Nginx{
-		Id: id,
-	}
-	o := orm.NewOrm()
-	err = o.Read(&nginx)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	instance := ngx.GetInstance(&nginx)
-	isRun, msg := instance.Status()
-	c.setData(isRun).setMsg(msg).json()
-}
+package controllers
+
+import (
+	"encoding/json"
+	"github.com/astaxie/beego/logs"
+	"github.com/astaxie/beego/orm"
+	"server/models"
+	ngx "server/nginx"
+	"strconv"
+)
+
+type NginxController struct {
+	BaseController
+}
+
+const ReplacePassword = "******"
+
+// Get getAll
+func (c *NginxController) Get() {
+	o := orm.NewOrm()
+	qs := o.QueryTable("nginx")
+	var list []*models.Nginx
+	_, err := qs.All(&list)
+	for i := range list {
+		item := list[i]
+		if item.Password != "" {
+			item.Password = ReplacePassword
+		}
+	}
+
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	} else {
+		c.setData(list).json()
+	}
+}
+
+// Post add nginx instance
+func (c *NginxController) Post() {
+	var nginx models.Nginx
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &nginx)
+	if err != nil {
+		logs.Error(err, string(c.Ctx.Input.RequestBody))
+		c.ErrorJson(err)
+		return
+	}
+	nginx.Check()
+	o := orm.NewOrm()
+	var saveErr error
+	if nginx.Id == 0 {
+		_, err = o.Insert(&nginx)
+		saveErr = err
+	} else {
+		tmp := models.Nginx{
+			Id: nginx.Id,
+		}
+		err = o.Read(&tmp)
+		if err != nil {
+			c.ErrorJson(err)
+			return
+		}
+		if nginx.Password == ReplacePassword {
+			nginx.Password = tmp.Password
+		}
+		nginx.HttpConf = tmp.HttpConf
+		_, err = o.Update(&nginx)
+		saveErr = err
+	}
+
+	if saveErr != nil {
+		c.ErrorJson(saveErr)
+		return
+	}
+	logs.Info("post", nginx)
+
+	instance := ngx.GetInstance(&nginx)
+	err = instance.Connect()
+	if err != nil {
+		c.setCode(1).setMsg(err.Error()).setData(nginx)
+		c.json()
+		return
+	}
+	out, err := instance.GetVersion()
+	if err != nil {
+		c.setCode(1).setMsg(err.Error()).setData(nginx)
+		c.json()
+		return
+	}
+	nginx.VersionInfo = out
+	_, _ = o.Update(&nginx, "VersionInfo")
+	c.setData(nginx).json()
+}
+
+// StartNginx startNginx
+func (c *NginxController) StartNginx() {
+	idStr := c.getParam(":id")
+	id, err := strconv.Atoi(idStr)
+	logs.Info("id", id)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	var nginx = models.Nginx{
+		Id: id,
+	}
+	o := orm.NewOrm()
+	err = o.Read(&nginx)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	instance := ngx.GetInstance(&nginx)
+	err = instance.Start()
+	isRun, msg := instance.Status()
+	c.setData(isRun).setMsg(msg).json()
+}
+
+// StopNginx add nginx instance
+func (c *NginxController) StopNginx() {
+	idStr := c.getParam(":id")
+	id, err := strconv.Atoi(idStr)
+	logs.Info("id", id)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+
+	var nginx = models.Nginx{
+		Id: id,
+	}
+	o := orm.NewOrm()
+	err = o.Read(&nginx)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	instance := ngx.GetInstance(&nginx)
+	err = instance.Stop()
+	isRun, msg := instance.Status()
+	c.setData(isRun).setMsg(msg).json()
+}
+
+// RefreshHttp nginx detail data
+func (c *NginxController) RefreshHttp() {
+	var nginx models.Nginx
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &nginx)
+	if err != nil {
+		logs.Error(err, string(c.Ctx.Input.RequestBody))
+		c.ErrorJson(err)
+		return
+	}
+
+	logs.Info("id", nginx)
+
+	o := orm.NewOrm()
+	if nginx.HttpConf != "" {
+		_, err = o.Update(&nginx, "HttpConf","HttpData")
+		if err != nil {
+			c.ErrorJson(err)
+			return
+		}
+	}
+	err = o.Read(&nginx)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	ins := ngx.GetInstance(&nginx)
+	err = ins.RefreshHttp(nginx)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	c.setData(nginx)
+	c.json()
+}
+
+// GetNginx nginx detail data
+func (c *NginxController) GetNginx() {
+	idStr := c.getParam(":id")
+	id, err := strconv.Atoi(idStr)
+	logs.Info("id", id)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	o := orm.NewOrm()
+
+	var nginx = models.Nginx{Id: id}
+	err = o.Read(&nginx)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	if nginx.Password != "" {
+		nginx.Password = ReplacePassword
+	}
+	c.addRespData("nginx", nginx)
+
+	var servers []models.ServerHost
+	_, err = o.QueryTable((*models.ServerHost)(nil)).Filter("NginxId", id).All(&servers)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	c.addRespData("servers", servers)
+	c.json()
+}
+
+// DelNginx delete a instance
+func (c *NginxController) DelNginx() {
+	id, err := c.getIntParam(":id")
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	o := orm.NewOrm()
+	nginx := models.Nginx{Id: id}
+	count, err := o.Delete(&nginx)
+	if err != nil {
+		c.ErrorJson(err)
+	} else {
+		c.setData(count).json()
+	}
+}
+
+// StopNginx add nginx instance
+func (c *NginxController) StatusNginx() {
+	idStr := c.getParam(":id")
+	id, err := strconv.Atoi(idStr)
+	logs.Info("id", id)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+
+	var nginx = models.Nginx{
+		Id: id,
+	}
+	o := orm.NewOrm()
+	err = o.Read(&nginx)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	instance := ngx.GetInstance(&nginx)
+	isRun, msg := instance.Status()
+	c.setData(isRun).setMsg(msg).json()
+}

+ 128 - 128
server/controllers/server.go

@@ -1,128 +1,128 @@
-package controllers
-
-import (
-	"encoding/json"
-	"github.com/astaxie/beego/orm"
-	"server/models"
-	nginx2 "server/nginx"
-)
-
-type ServerController struct {
-	BaseController
-}
-
-// Get getAllServers
-func (c *ServerController) Get() {
-
-	id, err := c.GetInt("id", 0)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-
-	o := orm.NewOrm()
-	server := models.ServerHost{Id: id}
-	err = o.Read(&server)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	c.setData(server).json()
-}
-
-// Post add or update nginx instance
-func (c *ServerController) Post() {
-	var server models.ServerHost
-	err := json.Unmarshal(c.Ctx.Input.RequestBody, &server)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	o := orm.NewOrm()
-	var saveErr error
-	if server.Id > 0 {
-		tmp := models.ServerHost{Id: server.Id}
-		err := o.Read(&tmp, "last_name")
-		if err == nil {
-			server.LastName = tmp.LastName
-			server.ServerConf = tmp.ServerConf
-		}
-		_, saveErr = o.Update(&server)
-	} else {
-		_, saveErr = o.Insert(&server)
-	}
-
-	if saveErr != nil {
-		c.ErrorJson(saveErr)
-	} else {
-		c.setData(server).json()
-	}
-}
-
-// Delete add or update nginx instance
-func (c *ServerController) Delete() {
-	var server models.ServerHost
-	err := json.Unmarshal(c.Ctx.Input.RequestBody, &server)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	o := orm.NewOrm()
-	err = o.Read(&server)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	nginx := models.Nginx{Id: server.NginxId}
-	err = o.Read(&nginx)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	ins := nginx2.GetInstance(&nginx)
-	server.Enable = false
-	err = ins.RefreshServer(server)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	delServer := models.ServerHost{Id: server.Id}
-	_, err = o.Delete(&delServer)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	c.setData("success").json()
-}
-
-// Refresh check and refresh to disk
-func (c *ServerController) Refresh() {
-	var postData models.ServerHost
-	err := json.Unmarshal(c.Ctx.Input.RequestBody, &postData)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	o := orm.NewOrm()
-	_, err = o.Update(&postData)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-
-	var nginx = models.Nginx{Id: postData.NginxId}
-	err = o.Read(&nginx)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	ins := nginx2.GetInstance(&nginx)
-	err = ins.RefreshServer(postData)
-	if err != nil {
-		c.ErrorJson(err)
-		return
-	}
-	postData.LastName = postData.Name
-	_, _ = o.Update(&postData)
-	c.setData(true).json()
-}
+package controllers
+
+import (
+	"encoding/json"
+	"github.com/astaxie/beego/orm"
+	"server/models"
+	nginx2 "server/nginx"
+)
+
+type ServerController struct {
+	BaseController
+}
+
+// Get getAllServers
+func (c *ServerController) Get() {
+
+	id, err := c.GetInt("id", 0)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+
+	o := orm.NewOrm()
+	server := models.ServerHost{Id: id}
+	err = o.Read(&server)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	c.setData(server).json()
+}
+
+// Post add or update nginx instance
+func (c *ServerController) Post() {
+	var server models.ServerHost
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &server)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	o := orm.NewOrm()
+	var saveErr error
+	if server.Id > 0 {
+		tmp := models.ServerHost{Id: server.Id}
+		err := o.Read(&tmp, "last_name")
+		if err == nil {
+			server.LastName = tmp.LastName
+			server.ServerConf = tmp.ServerConf
+		}
+		_, saveErr = o.Update(&server)
+	} else {
+		_, saveErr = o.Insert(&server)
+	}
+
+	if saveErr != nil {
+		c.ErrorJson(saveErr)
+	} else {
+		c.setData(server).json()
+	}
+}
+
+// Delete add or update nginx instance
+func (c *ServerController) Delete() {
+	var server models.ServerHost
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &server)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	o := orm.NewOrm()
+	err = o.Read(&server)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	nginx := models.Nginx{Id: server.NginxId}
+	err = o.Read(&nginx)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	ins := nginx2.GetInstance(&nginx)
+	server.Enable = false
+	err = ins.RefreshServer(server)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	delServer := models.ServerHost{Id: server.Id}
+	_, err = o.Delete(&delServer)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	c.setData("success").json()
+}
+
+// Refresh check and refresh to disk
+func (c *ServerController) Refresh() {
+	var postData models.ServerHost
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &postData)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	o := orm.NewOrm()
+	_, err = o.Update(&postData)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+
+	var nginx = models.Nginx{Id: postData.NginxId}
+	err = o.Read(&nginx)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	ins := nginx2.GetInstance(&nginx)
+	err = ins.RefreshServer(postData)
+	if err != nil {
+		c.ErrorJson(err)
+		return
+	}
+	postData.LastName = postData.Name
+	_, _ = o.Update(&postData)
+	c.setData(true).json()
+}

BIN
server/data/db/sqlite.db


BIN
server/data/sessions/4/0/40000f9d991d9b84f2cf3d7778d41f75


BIN
server/data/sessions/7/d/7d52340d3b7d72782a0e8a8c9359e913


+ 1 - 0
server/db/db.go

@@ -26,6 +26,7 @@ func Init() {
 	orm.RegisterModel(new(models.Nginx))
 	orm.RegisterModel(new(models.ServerHost))
 	orm.RegisterModel(new(models.NginxCerts))
+	orm.RegisterModel(new(models.User))
 
 	orm.RunSyncdb("default", false, true)
 

+ 4 - 2
server/go.mod

@@ -5,6 +5,7 @@ go 1.18
 require github.com/astaxie/beego v1.12.1
 
 require (
+	github.com/beego/beego/v2 v2.1.0
 	github.com/mattn/go-sqlite3 v1.14.17
 	github.com/mholt/archiver/v4 v4.0.0-alpha.8
 	github.com/pkg/sftp v1.13.5
@@ -19,6 +20,7 @@ require (
 	github.com/bodgit/windows v1.0.0 // indirect
 	github.com/connesc/cipherio v0.2.1 // indirect
 	github.com/dsnet/compress v0.0.1 // indirect
+	github.com/go-redis/redis/v7 v7.4.0 // indirect
 	github.com/golang/snappy v0.0.4 // indirect
 	github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect
 	github.com/hashicorp/errwrap v1.0.0 // indirect
@@ -29,6 +31,7 @@ require (
 	github.com/kr/fs v0.1.0 // indirect
 	github.com/nwaples/rardecode/v2 v2.0.0-beta.2 // indirect
 	github.com/pierrec/lz4/v4 v4.1.15 // indirect
+	github.com/pkg/errors v0.9.1 // indirect
 	github.com/shiena/ansicolor v0.0.0-20230509054315-a9deabde6e02 // indirect
 	github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
 	github.com/therootcompany/xz v1.0.1 // indirect
@@ -37,7 +40,6 @@ require (
 	golang.org/x/net v0.10.0 // indirect
 	golang.org/x/sys v0.9.0 // indirect
 	golang.org/x/text v0.10.0 // indirect
-	google.golang.org/appengine v1.6.7 // indirect
-	gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
 	gopkg.in/yaml.v2 v2.2.8 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
 )

+ 30 - 8
server/go.sum

@@ -23,6 +23,8 @@ github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY
 github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
 github.com/astaxie/beego v1.12.1 h1:dfpuoxpzLVgclveAXe4PyNKqkzgm5zF4tgF2B3kkM2I=
 github.com/astaxie/beego v1.12.1/go.mod h1:kPBWpSANNbSdIqOc8SUL9h+1oyBMZhROeYsXQDbidWQ=
+github.com/beego/beego/v2 v2.1.0 h1:Lk0FtQGvDQCx5V5yEu4XwDsIgt+QOlNjt5emUa3/ZmA=
+github.com/beego/beego/v2 v2.1.0/go.mod h1:6h36ISpaxNrrpJ27siTpXBG8d/Icjzsc7pU1bWpp0EE=
 github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ=
 github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU=
 github.com/bodgit/plumbing v1.2.0 h1:gg4haxoKphLjml+tgnecR4yLBV5zo4HAZGCtAh3xCzM=
@@ -45,21 +47,24 @@ github.com/couchbase/go-couchbase v0.0.0-20181122212707-3e9b6e1258bb/go.mod h1:T
 github.com/couchbase/gomemcached v0.0.0-20181122193126-5125a94a666c/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
 github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
 github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
-github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q=
 github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=
 github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
 github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
-github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk=
 github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
+github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
-github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
+github.com/go-redis/redis/v7 v7.4.0 h1:7obg6wUoj05T0EpY0o8B59S9w5yeMWql7sw2kwNW1x4=
+github.com/go-redis/redis/v7 v7.4.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
 github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -100,6 +105,8 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l
 github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
@@ -119,8 +126,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.10.5 h1:J+gdV2cUmX7ZqL2B0lFcW0m+egaHC2V3lpO8nWxyYiQ=
 github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
 github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
@@ -128,10 +135,17 @@ github.com/mholt/archiver/v4 v4.0.0-alpha.8 h1:tRGQuDVPh66WCOelqe6LIGh0gwmfwxUrS
 github.com/mholt/archiver/v4 v4.0.0-alpha.8/go.mod h1:5f7FUYGXdJWUjESffJaYR4R60VhnHxb2X3T1teMyv5A=
 github.com/nwaples/rardecode/v2 v2.0.0-beta.2 h1:e3mzJFJs4k83GXBEiTaQ5HgSc/kOK8q0rDaRO0MPaOk=
 github.com/nwaples/rardecode/v2 v2.0.0-beta.2/go.mod h1:yntwv/HfMc/Hbvtq9I19D1n58te3h6KsqCf3GxyfBGY=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
+github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
+github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
 github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0=
 github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/sftp v1.13.5 h1:a3RLUqkyjYRtBTZJZ1VRrKbN3zhuPLlUc3sphVz81go=
 github.com/pkg/sftp v1.13.5/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -152,8 +166,8 @@ github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXc
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
 github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
 github.com/therootcompany/xz v1.0.1 h1:CmOtsn1CbtmyYiusbfmhmkpAAETj0wBIH6kCYaX+xzw=
 github.com/therootcompany/xz v1.0.1/go.mod h1:3K3UH1yCKgBneZYhuQUvJ9HPD19UEXEI0BWbMn8qNMY=
@@ -201,6 +215,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -210,6 +225,7 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -228,6 +244,7 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -236,6 +253,7 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -299,8 +317,6 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
 google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
-google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
 google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@@ -326,12 +342,18 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

+ 7 - 0
server/main.go

@@ -1,12 +1,19 @@
 package main
 
 import (
+	"encoding/gob"
 	"github.com/astaxie/beego"
+	_ "github.com/beego/beego/v2/server/web/session/redis"
 	_ "server/config"
 	"server/db"
+	"server/models"
 	_ "server/routers"
 )
 
+func init() {
+	gob.Register(models.User{})
+}
+
 func main() {
 
 	db.Init()

+ 91 - 0
server/middleware/auth.go

@@ -0,0 +1,91 @@
+package middleware
+
+import (
+	"fmt"
+	"github.com/astaxie/beego"
+	"github.com/astaxie/beego/context"
+	"github.com/astaxie/beego/logs"
+	"github.com/astaxie/beego/session"
+	"github.com/beego/beego/v2/client/httplib"
+	"net/http"
+	"server/models"
+)
+
+type ThirdSession struct {
+	Enable     bool
+	CookieName string
+	CheckUrl   string
+}
+
+var thirdSession = ThirdSession{
+	Enable:     false,
+	CookieName: "",
+	CheckUrl:   "",
+}
+
+func init() {
+	beego.BConfig.WebConfig.Session.SessionAutoSetCookie = true
+
+	thirdSession.Enable = beego.AppConfig.DefaultBool("thirdsessionenable", false)
+	thirdSession.CookieName = beego.AppConfig.DefaultString("thirdsessionname", "")
+	thirdSession.CheckUrl = beego.AppConfig.DefaultString("thirdsessioncheckurl", "")
+	if thirdSession.Enable && (len(thirdSession.CookieName) == 0 || len(thirdSession.CheckUrl) == 0) {
+		logs.Info("no thirdsessionname or thirdsessioncheckurl info,skip !")
+		thirdSession.Enable = false
+	}
+}
+
+func checkThirdSession(ctx *context.Context, sess session.Store) {
+	if !thirdSession.Enable {
+		return
+	}
+	cookie, err := ctx.Request.Cookie(thirdSession.CookieName)
+	if err != nil {
+		logs.Warn("no cookie", err)
+		return
+	}
+	req := httplib.Get(thirdSession.CheckUrl)
+	req.SetEnableCookie(true)
+	req.SetCookie(cookie)
+	user := models.User{}
+	err = req.ToJSON(&user)
+	if err != nil {
+		logs.Warn("check third session fail ", err)
+		return
+	}
+	err = sess.Set("user", user)
+	if err != nil {
+		logs.Warn("set session data fail ", err)
+		return
+	}
+	logs.Debug("check third session ok ", user)
+}
+
+func AuthFilter(ctx *context.Context) {
+	sess := ctx.Input.CruSession
+	defer sess.SessionRelease(ctx.ResponseWriter)
+	data := sess.Get("user")
+	if data == nil {
+		checkThirdSession(ctx, sess)
+	}
+	data = sess.Get("user")
+	if data == nil {
+		writeForbidden(ctx.ResponseWriter)
+		return
+	}
+	user := data.(models.User)
+	if len(user.Account) == 0 {
+		writeForbidden(ctx.ResponseWriter)
+		return
+	}
+	logs.Info(fmt.Sprintf("request uri: %s, uid: %s", ctx.Request.RequestURI, user.Account))
+}
+
+func writeForbidden(w http.ResponseWriter) {
+	w.WriteHeader(403)
+	_, err := w.Write([]byte("403 Forbidden\n"))
+	if err != nil {
+		logs.Warn("writeForbidden write error", err)
+		return
+	}
+}

+ 16 - 16
server/models/file.go

@@ -1,16 +1,16 @@
-package models
-
-type FileReq struct {
-	Path string `json:"path"`
-	Key  string `json:"key"`
-}
-
-type DeployReq struct {
-	// 已上传的文件夹根目录
-	Key     string `json:"key"`
-	NginxId int    `json:"nginxId"`
-	// 部署目录
-	Dir string `json:"dir"`
-	// 是否先清空文件夹,再部署
-	Clear bool `json:"clear"`
-}
+package models
+
+type FileReq struct {
+	Path string `json:"path"`
+	Key  string `json:"key"`
+}
+
+type DeployReq struct {
+	// 已上传的文件夹根目录
+	Key     string `json:"key"`
+	NginxId int    `json:"nginxId"`
+	// 部署目录
+	Dir string `json:"dir"`
+	// 是否先清空文件夹,再部署
+	Clear bool `json:"clear"`
+}

+ 2 - 0
server/models/nginx.go

@@ -46,6 +46,7 @@ type ServerHost struct {
 	// is tcp or udp, default is false
 	IsStream bool   `json:"isStream"`
 	NginxId  int    `json:"nginxId"`
+	Uid      string `json:"uid"`
 	Name     string `json:"name"`
 	// 记录一下上一次刷新保存的名字
 	LastName string `json:"lastName"`
@@ -61,6 +62,7 @@ type ServerHost struct {
 type NginxCerts struct {
 	Id          int    `orm:"pk;auto" json:"id"`
 	ServiceName string `orm:"unique" json:"serviceName"`
+	Uid         string `json:"uid"`
 	Key         string `json:"key"`
 	Pem         string `json:"pem"`
 	NginxId     int    `json:"nginxId"`

+ 14 - 0
server/models/user.go

@@ -0,0 +1,14 @@
+package models
+
+// User 用户表
+type User struct {
+	Id int `orm:"pk;auto" json:"id"`
+	// 用户账号,唯一标识, Uid
+	Account  string `orm:"unique" json:"account"`
+	Nickname string `json:"nickname"`
+	// 用户角色,admin为管理员,多个使用逗号分割
+	// 现在没多大用
+	Roles    string `json:"roles"`
+	Password string `json:"password"`
+	Remark   string `json:"remark"`
+}

+ 285 - 285
server/nginx/instance.go

@@ -1,285 +1,285 @@
-package nginx
-
-import (
-	"errors"
-	"fmt"
-	"github.com/astaxie/beego/logs"
-	"server/models"
-	"strings"
-	"time"
-)
-
-var logger = logs.GetLogger()
-
-type Dirs struct {
-	DataDir   string
-	ConfDir   string
-	StreamDir string
-	CertsDir  string
-	BackupDir string
-}
-
-type InstanceInter interface {
-	Connect() error
-	Close(onlySession bool)
-	Run(cmd string) (string, error)
-	SetNginx(nginx *models.Nginx)
-	SendFile(src string, remote string) error
-}
-
-type Instance struct {
-	InstanceInter
-	nginx *models.Nginx
-}
-
-func (n *Instance) CheckDirs() Dirs {
-	nginx := n.nginx
-	dataDir := nginx.DataDir
-	if strings.HasSuffix(dataDir, "/") {
-		dataDir = dataDir[0 : len(dataDir)-1]
-	}
-	streamDir := fmt.Sprintf("%s/stream.d", dataDir)
-	certsDir := fmt.Sprintf("%s/certs", dataDir)
-	backupDir := fmt.Sprintf("%s/backup", dataDir)
-	confDir := fmt.Sprintf("%s/conf.d", dataDir)
-	_, _ = n.Run(fmt.Sprintf("mkdir -p %s %s %s %s", confDir, streamDir, certsDir, backupDir))
-	return Dirs{
-		DataDir:   dataDir,
-		ConfDir:   confDir,
-		StreamDir: streamDir,
-		CertsDir:  certsDir,
-		BackupDir: backupDir,
-	}
-}
-
-func (n *Instance) RefreshServer(server models.ServerHost) error {
-	dirs := n.CheckDirs()
-	var confDir string
-	if server.IsStream {
-		confDir = dirs.StreamDir
-	} else {
-		confDir = dirs.ConfDir
-	}
-	// id_server_name.conf
-	realName := fmt.Sprintf("%s/%d_%s.conf", confDir, server.Id, server.Name)
-	var lastName string
-	if server.LastName != "" {
-		lastName = fmt.Sprintf("%s/%d_%s.conf", confDir, server.Id, server.LastName)
-	} else {
-		lastName = fmt.Sprintf("%s/%d_%s.conf", confDir, server.Id, server.Name)
-	}
-	backName := fmt.Sprintf("%s/%s.conf_%s", dirs.BackupDir, server.Name, time.Now().Format("20060102150405"))
-
-	res, err := n.Run(fmt.Sprintf("if [ -f %s ];then mv -f %s %s;fi;rm -rf %s/%d_*.conf", lastName, lastName, backName, confDir, server.Id))
-	if err != nil {
-		return err
-	}
-
-	defer n.Close(true)
-	if !server.Enable {
-		return nil
-	}
-	serverConf := strings.ReplaceAll(server.ServerConf, "\"", "\\\"")
-	serverConf = strings.ReplaceAll(serverConf, "$", "\\$")
-	cmd := fmt.Sprintf("echo \"%s\" > %s", serverConf, realName)
-	res, err = n.Run(cmd)
-	if err != nil {
-		logger.Printf("echo conf fail", err, res)
-		return err
-	}
-	if err := n.Check(); err != nil {
-		_, recoveryErr := n.Run(fmt.Sprintf("if [ -f %s ];then mv -f %s %s;fi", backName, backName, realName))
-		if recoveryErr != nil {
-			return errors.New(fmt.Sprintf("配置文件异常: %s;且文件恢复异常,请手动处理或者修正后重新刷新!", err.Error()))
-		}
-		return err
-	}
-	if err := n.Reload(); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (n *Instance) RefreshHttp(nginx models.Nginx) error {
-	dirs := n.CheckDirs()
-	var confDir = nginx.NginxDir
-
-	realName := fmt.Sprintf("%s/nginx.conf", dirs.DataDir)
-	linkName := fmt.Sprintf("%s/nginx.conf", confDir)
-	backName := fmt.Sprintf("%s/%d.http_%s", dirs.BackupDir, nginx.Id, time.Now().Format("060102150405"))
-
-	res, err := n.Run(fmt.Sprintf("find %s -name nginx.conf -type l -delete", confDir))
-	if err != nil {
-		logger.Printf("echo rm conf file fail", err, res)
-		return err
-	}
-	// 如果非软连接,就先mv 备份
-	res, err = n.Run(fmt.Sprintf("cd %s && if [ -f nginx.conf ];then mv -f nginx.conf nginx.conf.bak ;fi", confDir))
-	defer n.Close(true)
-
-	httpConf := strings.ReplaceAll(nginx.HttpConf, "\"", "\\\"")
-	httpConf = strings.ReplaceAll(httpConf, "$", "\\$")
-	cmd := fmt.Sprintf("echo \"%s\" > %s && cp %s %s", httpConf, realName, realName, backName)
-	res, err = n.Run(cmd)
-	if err != nil {
-		logger.Printf("echo conf fail", err, res)
-		return err
-	}
-	res, err = n.Run(fmt.Sprintf("ln -s %s %s", realName, linkName))
-	if err != nil {
-		return err
-	}
-	if err := n.Check(); err != nil {
-		return err
-	}
-	if err := n.Reload(); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (n *Instance) GetVersion() (string, error) {
-	out, err := n.Run(fmt.Sprintf("%s -V", n.nginx.NginxPath))
-	if err != nil {
-		logs.Warn("CheckConf", err)
-		return "", err
-	}
-	logs.Info("CheckConf", out)
-	return out, err
-}
-
-func (n *Instance) Check() error {
-	nginx := n.nginx
-	_ = n.CheckDirs()
-	out, err := n.Run(fmt.Sprintf("%s -t", nginx.NginxPath))
-	if err != nil {
-		logs.Warn("CheckConf fail", err, out)
-		return err
-	}
-	logs.Info("CheckConf", out)
-	return nil
-}
-
-// Reload 如果nginx未启动,这个返回码为 1
-func (n *Instance) Reload() error {
-	isRun, _ := n.Status()
-	if !isRun {
-		logs.Info("nginx not running")
-		return nil
-	}
-	var cmd string
-	if n.nginx.IsServer {
-		cmd = "service nginx reload"
-	} else {
-		cmd = fmt.Sprintf("%s -s reload", n.nginx.NginxPath)
-	}
-	out, err := n.Run(cmd)
-	if err != nil {
-		logs.Warn("Reload", err)
-		return err
-	}
-	logs.Info("Reload", out)
-	return nil
-}
-
-func (n *Instance) Status() (bool, string) {
-
-	var cmd string
-	if n.nginx.IsServer {
-		cmd = "service nginx status"
-	} else { // 得想其它办法,这个没有直接的命令,ps也不见得有
-		cmd = fmt.Sprintf("%s -s reload", n.nginx.NginxPath)
-	}
-	out, err := n.Run(cmd)
-	if err != nil {
-		logs.Warn("Status", err)
-		return false, out
-	}
-	logs.Info("Status", out)
-	return true, out
-}
-
-// Start 如果已经启动,这里会返回-1
-func (n *Instance) Start() error {
-	var cmd string
-	if n.nginx.IsServer {
-		cmd = "service nginx start"
-	} else {
-		cmd = fmt.Sprintf("%s", n.nginx.NginxPath)
-	}
-	go func() {
-		out, err := n.Run(cmd)
-		if err != nil {
-			logs.Warn("Start", err)
-		}
-		logs.Info("Start", out)
-	}()
-	time.Sleep(time.Second * 5)
-	return nil
-}
-
-func (n *Instance) Stop() error {
-	var cmd string
-	if n.nginx.IsServer {
-		cmd = "service nginx stop"
-	} else {
-		cmd = fmt.Sprintf("%s -s stop", n.nginx.NginxPath)
-	}
-	out, err := n.Run(cmd)
-	if err != nil {
-		logs.Warn("Stop", err)
-		return err
-	}
-	logs.Info("Stop", out)
-	return nil
-}
-
-func (n *Instance) GetCerts() string {
-	dirs := n.CheckDirs()
-	cmd := fmt.Sprintf("cd %s && /usr/bin/ls -l *.key | /usr/bin/awk '{print $9}'", dirs.CertsDir)
-	out, err := n.Run(cmd)
-	if err != nil {
-		logs.Warn("GetCerts", err)
-		return ""
-	}
-	logs.Info("GetCerts", out)
-	return out
-}
-
-func (n *Instance) GetCertData(name string) (*models.NginxCerts, error) {
-	cert := models.NginxCerts{
-		ServiceName: name,
-	}
-	dirs := n.CheckDirs()
-	pemPath := fmt.Sprintf("%s/%s.pem", dirs.CertsDir, name)
-	keyPath := fmt.Sprintf("%s/%s.key", dirs.CertsDir, name)
-	cmd := "/usr/bin/cat " + keyPath
-	out, err := n.Run(cmd)
-	if err != nil {
-		logs.Warn("Stop", err)
-		return &cert, err
-	}
-	cert.Key = out
-	cmd = "/usr/bin/cat " + pemPath
-	out, err = n.Run(cmd)
-	if err != nil {
-		logs.Warn("Stop", err)
-		return &cert, err
-	}
-	cert.Pem = out
-	return &cert, nil
-}
-
-func (n *Instance) SaveCerts(cert *models.NginxCerts) error {
-	dirs := n.CheckDirs()
-	pemPath := fmt.Sprintf("%s/%s.pem", dirs.CertsDir, cert.ServiceName)
-	keyPath := fmt.Sprintf("%s/%s.key", dirs.CertsDir, cert.ServiceName)
-	cmd := fmt.Sprintf("echo '%s' > %s;echo '%s' > %s", cert.Pem, pemPath, cert.Key, keyPath)
-	out, err := n.Run(cmd)
-	if err != nil {
-		logs.Warn("SaveCerts", err)
-		return err
-	}
-	logs.Info("SaveCerts ", out)
-	return nil
-}
+package nginx
+
+import (
+	"errors"
+	"fmt"
+	"github.com/astaxie/beego/logs"
+	"server/models"
+	"strings"
+	"time"
+)
+
+var logger = logs.GetLogger()
+
+type Dirs struct {
+	DataDir   string
+	ConfDir   string
+	StreamDir string
+	CertsDir  string
+	BackupDir string
+}
+
+type InstanceInter interface {
+	Connect() error
+	Close(onlySession bool)
+	Run(cmd string) (string, error)
+	SetNginx(nginx *models.Nginx)
+	SendFile(src string, remote string) error
+}
+
+type Instance struct {
+	InstanceInter
+	nginx *models.Nginx
+}
+
+func (n *Instance) CheckDirs() Dirs {
+	nginx := n.nginx
+	dataDir := nginx.DataDir
+	if strings.HasSuffix(dataDir, "/") {
+		dataDir = dataDir[0 : len(dataDir)-1]
+	}
+	streamDir := fmt.Sprintf("%s/stream.d", dataDir)
+	certsDir := fmt.Sprintf("%s/certs", dataDir)
+	backupDir := fmt.Sprintf("%s/backup", dataDir)
+	confDir := fmt.Sprintf("%s/conf.d", dataDir)
+	_, _ = n.Run(fmt.Sprintf("mkdir -p %s %s %s %s", confDir, streamDir, certsDir, backupDir))
+	return Dirs{
+		DataDir:   dataDir,
+		ConfDir:   confDir,
+		StreamDir: streamDir,
+		CertsDir:  certsDir,
+		BackupDir: backupDir,
+	}
+}
+
+func (n *Instance) RefreshServer(server models.ServerHost) error {
+	dirs := n.CheckDirs()
+	var confDir string
+	if server.IsStream {
+		confDir = dirs.StreamDir
+	} else {
+		confDir = dirs.ConfDir
+	}
+	// id_server_name.conf
+	realName := fmt.Sprintf("%s/%d_%s.conf", confDir, server.Id, server.Name)
+	var lastName string
+	if server.LastName != "" {
+		lastName = fmt.Sprintf("%s/%d_%s.conf", confDir, server.Id, server.LastName)
+	} else {
+		lastName = fmt.Sprintf("%s/%d_%s.conf", confDir, server.Id, server.Name)
+	}
+	backName := fmt.Sprintf("%s/%s.conf_%s", dirs.BackupDir, server.Name, time.Now().Format("20060102150405"))
+
+	res, err := n.Run(fmt.Sprintf("if [ -f %s ];then mv -f %s %s;fi;rm -rf %s/%d_*.conf", lastName, lastName, backName, confDir, server.Id))
+	if err != nil {
+		return err
+	}
+
+	defer n.Close(true)
+	if !server.Enable {
+		return nil
+	}
+	serverConf := strings.ReplaceAll(server.ServerConf, "\"", "\\\"")
+	serverConf = strings.ReplaceAll(serverConf, "$", "\\$")
+	cmd := fmt.Sprintf("echo \"%s\" > %s", serverConf, realName)
+	res, err = n.Run(cmd)
+	if err != nil {
+		logger.Printf("echo conf fail", err, res)
+		return err
+	}
+	if err := n.Check(); err != nil {
+		_, recoveryErr := n.Run(fmt.Sprintf("if [ -f %s ];then mv -f %s %s;fi", backName, backName, realName))
+		if recoveryErr != nil {
+			return errors.New(fmt.Sprintf("配置文件异常: %s;且文件恢复异常,请手动处理或者修正后重新刷新!", err.Error()))
+		}
+		return err
+	}
+	if err := n.Reload(); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (n *Instance) RefreshHttp(nginx models.Nginx) error {
+	dirs := n.CheckDirs()
+	var confDir = nginx.NginxDir
+
+	realName := fmt.Sprintf("%s/nginx.conf", dirs.DataDir)
+	linkName := fmt.Sprintf("%s/nginx.conf", confDir)
+	backName := fmt.Sprintf("%s/%d.http_%s", dirs.BackupDir, nginx.Id, time.Now().Format("060102150405"))
+
+	res, err := n.Run(fmt.Sprintf("find %s -name nginx.conf -type l -delete", confDir))
+	if err != nil {
+		logger.Printf("echo rm conf file fail", err, res)
+		return err
+	}
+	// 如果非软连接,就先mv 备份
+	res, err = n.Run(fmt.Sprintf("cd %s && if [ -f nginx.conf ];then mv -f nginx.conf nginx.conf.bak ;fi", confDir))
+	defer n.Close(true)
+
+	httpConf := strings.ReplaceAll(nginx.HttpConf, "\"", "\\\"")
+	httpConf = strings.ReplaceAll(httpConf, "$", "\\$")
+	cmd := fmt.Sprintf("echo \"%s\" > %s && cp %s %s", httpConf, realName, realName, backName)
+	res, err = n.Run(cmd)
+	if err != nil {
+		logger.Printf("echo conf fail", err, res)
+		return err
+	}
+	res, err = n.Run(fmt.Sprintf("ln -s %s %s", realName, linkName))
+	if err != nil {
+		return err
+	}
+	if err := n.Check(); err != nil {
+		return err
+	}
+	if err := n.Reload(); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (n *Instance) GetVersion() (string, error) {
+	out, err := n.Run(fmt.Sprintf("%s -V", n.nginx.NginxPath))
+	if err != nil {
+		logs.Warn("CheckConf", err)
+		return "", err
+	}
+	logs.Info("CheckConf", out)
+	return out, err
+}
+
+func (n *Instance) Check() error {
+	nginx := n.nginx
+	_ = n.CheckDirs()
+	out, err := n.Run(fmt.Sprintf("%s -t", nginx.NginxPath))
+	if err != nil {
+		logs.Warn("CheckConf fail", err, out)
+		return err
+	}
+	logs.Info("CheckConf", out)
+	return nil
+}
+
+// Reload 如果nginx未启动,这个返回码为 1
+func (n *Instance) Reload() error {
+	isRun, _ := n.Status()
+	if !isRun {
+		logs.Info("nginx not running")
+		return nil
+	}
+	var cmd string
+	if n.nginx.IsServer {
+		cmd = "service nginx reload"
+	} else {
+		cmd = fmt.Sprintf("%s -s reload", n.nginx.NginxPath)
+	}
+	out, err := n.Run(cmd)
+	if err != nil {
+		logs.Warn("Reload", err)
+		return err
+	}
+	logs.Info("Reload", out)
+	return nil
+}
+
+func (n *Instance) Status() (bool, string) {
+
+	var cmd string
+	if n.nginx.IsServer {
+		cmd = "service nginx status"
+	} else { // 得想其它办法,这个没有直接的命令,ps也不见得有
+		cmd = fmt.Sprintf("%s -s reload", n.nginx.NginxPath)
+	}
+	out, err := n.Run(cmd)
+	if err != nil {
+		logs.Warn("Status", err)
+		return false, out
+	}
+	logs.Info("Status", out)
+	return true, out
+}
+
+// Start 如果已经启动,这里会返回-1
+func (n *Instance) Start() error {
+	var cmd string
+	if n.nginx.IsServer {
+		cmd = "service nginx start"
+	} else {
+		cmd = fmt.Sprintf("%s", n.nginx.NginxPath)
+	}
+	go func() {
+		out, err := n.Run(cmd)
+		if err != nil {
+			logs.Warn("Start", err)
+		}
+		logs.Info("Start", out)
+	}()
+	time.Sleep(time.Second * 5)
+	return nil
+}
+
+func (n *Instance) Stop() error {
+	var cmd string
+	if n.nginx.IsServer {
+		cmd = "service nginx stop"
+	} else {
+		cmd = fmt.Sprintf("%s -s stop", n.nginx.NginxPath)
+	}
+	out, err := n.Run(cmd)
+	if err != nil {
+		logs.Warn("Stop", err)
+		return err
+	}
+	logs.Info("Stop", out)
+	return nil
+}
+
+func (n *Instance) GetCerts() string {
+	dirs := n.CheckDirs()
+	cmd := fmt.Sprintf("cd %s && /usr/bin/ls -l *.key | /usr/bin/awk '{print $9}'", dirs.CertsDir)
+	out, err := n.Run(cmd)
+	if err != nil {
+		logs.Warn("GetCerts", err)
+		return ""
+	}
+	logs.Info("GetCerts", out)
+	return out
+}
+
+func (n *Instance) GetCertData(name string) (*models.NginxCerts, error) {
+	cert := models.NginxCerts{
+		ServiceName: name,
+	}
+	dirs := n.CheckDirs()
+	pemPath := fmt.Sprintf("%s/%s.pem", dirs.CertsDir, name)
+	keyPath := fmt.Sprintf("%s/%s.key", dirs.CertsDir, name)
+	cmd := "/usr/bin/cat " + keyPath
+	out, err := n.Run(cmd)
+	if err != nil {
+		logs.Warn("Stop", err)
+		return &cert, err
+	}
+	cert.Key = out
+	cmd = "/usr/bin/cat " + pemPath
+	out, err = n.Run(cmd)
+	if err != nil {
+		logs.Warn("Stop", err)
+		return &cert, err
+	}
+	cert.Pem = out
+	return &cert, nil
+}
+
+func (n *Instance) SaveCerts(cert *models.NginxCerts) error {
+	dirs := n.CheckDirs()
+	pemPath := fmt.Sprintf("%s/%s.pem", dirs.CertsDir, cert.ServiceName)
+	keyPath := fmt.Sprintf("%s/%s.key", dirs.CertsDir, cert.ServiceName)
+	cmd := fmt.Sprintf("echo '%s' > %s;echo '%s' > %s", cert.Pem, pemPath, cert.Key, keyPath)
+	out, err := n.Run(cmd)
+	if err != nil {
+		logs.Warn("SaveCerts", err)
+		return err
+	}
+	logs.Info("SaveCerts ", out)
+	return nil
+}

+ 66 - 66
server/nginx/local.go

@@ -1,66 +1,66 @@
-package nginx
-
-import (
-	"errors"
-	"fmt"
-	"github.com/astaxie/beego/logs"
-	"io"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"server/models"
-	"server/utils"
-)
-
-// LocalInstance 本地实例
-type LocalInstance struct {
-	nginx *models.Nginx
-}
-
-func (n *LocalInstance) Connect() error {
-	return nil
-}
-
-func (n *LocalInstance) Close(onlySession bool) {
-
-}
-func (n *LocalInstance) SetNginx(nginx *models.Nginx) {
-	n.nginx = nginx
-}
-
-func (n *LocalInstance) Run(cmd string) (string, error) {
-	logs.Info("Run: ", cmd)
-	command := exec.Command("/usr/bin/sh", "-c", cmd)
-	out, err := command.CombinedOutput()
-	if err != nil {
-		logs.Warn("local run cmd fail", err, string(out))
-		msg := fmt.Sprintf("%s;\n%s", err.Error(), string(out))
-		return string(out), errors.New(msg)
-	}
-	logs.Info("Run resp", string(out))
-	return string(out), nil
-}
-
-// SendFile Local 就是copy文件了
-func (n *LocalInstance) SendFile(src string, remote string) error {
-	srcFile, err := os.Open(src)
-	if err != nil {
-		return err
-	}
-	defer srcFile.Close()
-	base := filepath.Base(remote)
-	if !utils.IsExist(base) {
-		err = os.MkdirAll(base, 0777)
-	}
-	if err != nil {
-		return err
-	}
-	dst, err := os.OpenFile(remote, os.O_CREATE|os.O_WRONLY, 0777)
-	if err != nil {
-		return err
-	}
-	defer dst.Close()
-
-	_, err = io.Copy(dst, srcFile)
-	return err
-}
+package nginx
+
+import (
+	"errors"
+	"fmt"
+	"github.com/astaxie/beego/logs"
+	"io"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"server/models"
+	"server/utils"
+)
+
+// LocalInstance 本地实例
+type LocalInstance struct {
+	nginx *models.Nginx
+}
+
+func (n *LocalInstance) Connect() error {
+	return nil
+}
+
+func (n *LocalInstance) Close(onlySession bool) {
+
+}
+func (n *LocalInstance) SetNginx(nginx *models.Nginx) {
+	n.nginx = nginx
+}
+
+func (n *LocalInstance) Run(cmd string) (string, error) {
+	logs.Info("Run: ", cmd)
+	command := exec.Command("/usr/bin/sh", "-c", cmd)
+	out, err := command.CombinedOutput()
+	if err != nil {
+		logs.Warn("local run cmd fail", err, string(out))
+		msg := fmt.Sprintf("%s;\n%s", err.Error(), string(out))
+		return string(out), errors.New(msg)
+	}
+	logs.Info("Run resp", string(out))
+	return string(out), nil
+}
+
+// SendFile Local 就是copy文件了
+func (n *LocalInstance) SendFile(src string, remote string) error {
+	srcFile, err := os.Open(src)
+	if err != nil {
+		return err
+	}
+	defer srcFile.Close()
+	base := filepath.Base(remote)
+	if !utils.IsExist(base) {
+		err = os.MkdirAll(base, 0777)
+	}
+	if err != nil {
+		return err
+	}
+	dst, err := os.OpenFile(remote, os.O_CREATE|os.O_WRONLY, 0777)
+	if err != nil {
+		return err
+	}
+	defer dst.Close()
+
+	_, err = io.Copy(dst, srcFile)
+	return err
+}

+ 40 - 40
server/nginx/manager.go

@@ -1,40 +1,40 @@
-package nginx
-
-import (
-	"server/models"
-)
-
-var INSTANCES = map[int]*Instance{}
-
-func GetInstance(nginx *models.Nginx) *Instance {
-	var instance *Instance = INSTANCES[nginx.Id]
-	if instance != nil {
-		old := instance.nginx
-		if old.IpAddr != nginx.IpAddr || old.Port != nginx.Port || old.User != nginx.User || old.Password != nginx.Password {
-			instance.Close(false)
-			instance = nil
-			INSTANCES[nginx.Id] = nil
-		} else {
-			instance.nginx = nginx
-			instance.SetNginx(nginx)
-			return instance
-		}
-	}
-	if nginx.IsLocal {
-		instance = &Instance{
-			&LocalInstance{
-				nginx: nginx,
-			},
-			nginx,
-		}
-	} else {
-		instance = &Instance{
-			&RemoteInstance{
-				nginx: nginx,
-			},
-			nginx,
-		}
-	}
-	INSTANCES[nginx.Id] = instance
-	return instance
-}
+package nginx
+
+import (
+	"server/models"
+)
+
+var INSTANCES = map[int]*Instance{}
+
+func GetInstance(nginx *models.Nginx) *Instance {
+	var instance *Instance = INSTANCES[nginx.Id]
+	if instance != nil {
+		old := instance.nginx
+		if old.IpAddr != nginx.IpAddr || old.Port != nginx.Port || old.User != nginx.User || old.Password != nginx.Password {
+			instance.Close(false)
+			instance = nil
+			INSTANCES[nginx.Id] = nil
+		} else {
+			instance.nginx = nginx
+			instance.SetNginx(nginx)
+			return instance
+		}
+	}
+	if nginx.IsLocal {
+		instance = &Instance{
+			&LocalInstance{
+				nginx: nginx,
+			},
+			nginx,
+		}
+	} else {
+		instance = &Instance{
+			&RemoteInstance{
+				nginx: nginx,
+			},
+			nginx,
+		}
+	}
+	INSTANCES[nginx.Id] = instance
+	return instance
+}

+ 127 - 127
server/nginx/remote.go

@@ -1,127 +1,127 @@
-package nginx
-
-import (
-	"errors"
-	"fmt"
-	"github.com/astaxie/beego/logs"
-	"github.com/pkg/sftp"
-	"golang.org/x/crypto/ssh"
-	"io"
-	"net"
-	"os"
-	"server/models"
-	"time"
-)
-
-// RemoteInstance 远程
-type RemoteInstance struct {
-	nginx      *models.Nginx
-	client     *ssh.Client
-	LastResult string
-}
-
-func (n *RemoteInstance) Connect() error {
-	if n.client != nil {
-		return nil
-	}
-	config := ssh.ClientConfig{}
-	config.SetDefaults()
-	config.User = n.nginx.User
-	config.Auth = []ssh.AuthMethod{
-		ssh.Password(n.nginx.Password),
-	}
-	config.HostKeyCallback = func(hostname string, remote net.Addr, key ssh.PublicKey) error {
-		return nil
-	}
-	config.Timeout = time.Second * 60
-	addr := fmt.Sprintf("%s:%d", n.nginx.IpAddr, n.nginx.Port)
-	client, err := ssh.Dial("tcp", addr, &config)
-	if err != nil {
-		logs.Warn("connect error", err)
-		return err
-	}
-	n.client = client
-	go n.onDisConnect()
-	return nil
-}
-
-// Run RemoteInstance 这里应该要处理session断开的流程吧
-func (n *RemoteInstance) Run(cmd string) (string, error) {
-	logs.Info("Run: ", cmd)
-	if n.client == nil {
-		err := n.Connect()
-		if err != nil {
-			return "", err
-		}
-	}
-	session, err := n.client.NewSession()
-	if err != nil {
-		logs.Warn("NewSession fail", err)
-		return "", err
-	}
-	defer session.Close()
-	buf, err := session.CombinedOutput(cmd)
-	n.LastResult = string(buf)
-	logger.Printf("out: %v", n.LastResult)
-	if err != nil {
-		err = errors.New(fmt.Sprintf("%s;\n%s", err.Error(), n.LastResult))
-	}
-	return n.LastResult, err
-}
-
-func (n *RemoteInstance) Close(onlySession bool) {
-	if onlySession {
-		return
-	}
-	if n.client != nil {
-		n.client.Close()
-		n.client = nil
-	}
-}
-
-func (n *RemoteInstance) onDisConnect() {
-	if n.client != nil {
-		err := n.client.Wait()
-		logger.Printf("disconnect", err)
-	}
-	n.client = nil
-}
-func (n *RemoteInstance) SetNginx(nginx *models.Nginx) {
-	n.nginx = nginx
-}
-
-func (n *RemoteInstance) getSSHConfig() ssh.ClientConfig {
-	config := ssh.ClientConfig{}
-	config.SetDefaults()
-	config.User = n.nginx.User
-	config.Auth = []ssh.AuthMethod{
-		ssh.Password(n.nginx.Password),
-	}
-	config.HostKeyCallback = func(hostname string, remote net.Addr, key ssh.PublicKey) error {
-		return nil
-	}
-	config.Timeout = time.Second * 60
-	return config
-}
-
-// SendFile RemoteInstance 这里应该要处理session断开的流程吧
-func (n *RemoteInstance) SendFile(src string, remote string) error {
-	session, err := sftp.NewClient(n.client)
-	if err != nil {
-		return err
-	}
-	defer session.Close()
-	srcFile, err := os.Open(src)
-	if err != nil {
-		return err
-	}
-	defer srcFile.Close()
-	dstFile, err := session.Create(remote)
-	if err != nil {
-		return err
-	}
-	defer dstFile.Close()
-	l, err := io.Copy(dstFile, srcFile)
-	logs.Info("sendFile ok with size: ", l)
-	return err
-}
+package nginx
+
+import (
+	"errors"
+	"fmt"
+	"github.com/astaxie/beego/logs"
+	"github.com/pkg/sftp"
+	"golang.org/x/crypto/ssh"
+	"io"
+	"net"
+	"os"
+	"server/models"
+	"time"
+)
+
+// RemoteInstance 远程
+type RemoteInstance struct {
+	nginx      *models.Nginx
+	client     *ssh.Client
+	LastResult string
+}
+
+func (n *RemoteInstance) Connect() error {
+	if n.client != nil {
+		return nil
+	}
+	config := ssh.ClientConfig{}
+	config.SetDefaults()
+	config.User = n.nginx.User
+	config.Auth = []ssh.AuthMethod{
+		ssh.Password(n.nginx.Password),
+	}
+	config.HostKeyCallback = func(hostname string, remote net.Addr, key ssh.PublicKey) error {
+		return nil
+	}
+	config.Timeout = time.Second * 60
+	addr := fmt.Sprintf("%s:%d", n.nginx.IpAddr, n.nginx.Port)
+	client, err := ssh.Dial("tcp", addr, &config)
+	if err != nil {
+		logs.Warn("connect error", err)
+		return err
+	}
+	n.client = client
+	go n.onDisConnect()
+	return nil
+}
+
+// Run RemoteInstance 这里应该要处理session断开的流程吧
+func (n *RemoteInstance) Run(cmd string) (string, error) {
+	logs.Info("Run: ", cmd)
+	if n.client == nil {
+		err := n.Connect()
+		if err != nil {
+			return "", err
+		}
+	}
+	session, err := n.client.NewSession()
+	if err != nil {
+		logs.Warn("NewSession fail", err)
+		return "", err
+	}
+	defer session.Close()
+	buf, err := session.CombinedOutput(cmd)
+	n.LastResult = string(buf)
+	logger.Printf("out: %v", n.LastResult)
+	if err != nil {
+		err = errors.New(fmt.Sprintf("%s;\n%s", err.Error(), n.LastResult))
+	}
+	return n.LastResult, err
+}
+
+func (n *RemoteInstance) Close(onlySession bool) {
+	if onlySession {
+		return
+	}
+	if n.client != nil {
+		n.client.Close()
+		n.client = nil
+	}
+}
+
+func (n *RemoteInstance) onDisConnect() {
+	if n.client != nil {
+		err := n.client.Wait()
+		logger.Printf("disconnect", err)
+	}
+	n.client = nil
+}
+func (n *RemoteInstance) SetNginx(nginx *models.Nginx) {
+	n.nginx = nginx
+}
+
+func (n *RemoteInstance) getSSHConfig() ssh.ClientConfig {
+	config := ssh.ClientConfig{}
+	config.SetDefaults()
+	config.User = n.nginx.User
+	config.Auth = []ssh.AuthMethod{
+		ssh.Password(n.nginx.Password),
+	}
+	config.HostKeyCallback = func(hostname string, remote net.Addr, key ssh.PublicKey) error {
+		return nil
+	}
+	config.Timeout = time.Second * 60
+	return config
+}
+
+// SendFile RemoteInstance 这里应该要处理session断开的流程吧
+func (n *RemoteInstance) SendFile(src string, remote string) error {
+	session, err := sftp.NewClient(n.client)
+	if err != nil {
+		return err
+	}
+	defer session.Close()
+	srcFile, err := os.Open(src)
+	if err != nil {
+		return err
+	}
+	defer srcFile.Close()
+	dstFile, err := session.Create(remote)
+	if err != nil {
+		return err
+	}
+	defer dstFile.Close()
+	l, err := io.Copy(dstFile, srcFile)
+	logs.Info("sendFile ok with size: ", l)
+	return err
+}

+ 4 - 0
server/routers/router.go

@@ -2,12 +2,14 @@ package routers
 
 import (
 	"encoding/json"
+	"fmt"
 	"github.com/astaxie/beego"
 	"github.com/astaxie/beego/context"
 	"github.com/astaxie/beego/logs"
 	"net/http"
 	config2 "server/config"
 	"server/controllers"
+	"server/middleware"
 	"strings"
 )
 
@@ -33,6 +35,8 @@ func init() {
 	)
 	beego.AddNamespace(ns)
 
+	beego.InsertFilter(fmt.Sprintf("%s/**", config.BaseApi), beego.BeforeRouter, middleware.AuthFilter)
+
 	beego.Router("/nginx-ui/config.js", &controllers.ConfigController{})
 	// portal static assets
 	beego.SetStaticPath("/nginx-ui", "static/web")

+ 39 - 39
server/tests/default_test.go

@@ -1,39 +1,39 @@
-package test
-
-import (
-	"net/http"
-	"net/http/httptest"
-	"testing"
-	"runtime"
-	"path/filepath"
-	_ "server/routers"
-
-	"github.com/astaxie/beego"
-	. "github.com/smartystreets/goconvey/convey"
-)
-
-func init() {
-	_, file, _, _ := runtime.Caller(0)
-	apppath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, ".." + string(filepath.Separator))))
-	beego.TestBeegoInit(apppath)
-}
-
-
-// TestBeego is a sample to run an endpoint test
-func TestBeego(t *testing.T) {
-	r, _ := http.NewRequest("GET", "/", nil)
-	w := httptest.NewRecorder()
-	beego.BeeApp.Handlers.ServeHTTP(w, r)
-
-	beego.Trace("testing", "TestBeego", "Code[%d]\n%s", w.Code, w.Body.String())
-
-	Convey("Subject: Test Station Endpoint\n", t, func() {
-	        Convey("Status Code Should Be 200", func() {
-	                So(w.Code, ShouldEqual, 200)
-	        })
-	        Convey("The Result Should Not Be Empty", func() {
-	                So(w.Body.Len(), ShouldBeGreaterThan, 0)
-	        })
-	})
-}
-
+package test
+
+import (
+	"net/http"
+	"net/http/httptest"
+	"testing"
+	"runtime"
+	"path/filepath"
+	_ "server/routers"
+
+	"github.com/astaxie/beego"
+	. "github.com/smartystreets/goconvey/convey"
+)
+
+func init() {
+	_, file, _, _ := runtime.Caller(0)
+	apppath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, ".." + string(filepath.Separator))))
+	beego.TestBeegoInit(apppath)
+}
+
+
+// TestBeego is a sample to run an endpoint test
+func TestBeego(t *testing.T) {
+	r, _ := http.NewRequest("GET", "/", nil)
+	w := httptest.NewRecorder()
+	beego.BeeApp.Handlers.ServeHTTP(w, r)
+
+	beego.Trace("testing", "TestBeego", "Code[%d]\n%s", w.Code, w.Body.String())
+
+	Convey("Subject: Test Station Endpoint\n", t, func() {
+	        Convey("Status Code Should Be 200", func() {
+	                So(w.Code, ShouldEqual, 200)
+	        })
+	        Convey("The Result Should Not Be Empty", func() {
+	                So(w.Body.Len(), ShouldBeGreaterThan, 0)
+	        })
+	})
+}
+

+ 12 - 12
server/utils/cert.go

@@ -1,12 +1,12 @@
-package utils
-
-import (
-	"crypto/x509"
-	"encoding/pem"
-)
-
-func CheckHttps(pub string) (*x509.Certificate, error) {
-	skBlock, _ := pem.Decode([]byte(pub))
-	cert, err := x509.ParseCertificate(skBlock.Bytes)
-	return cert, err
-}
+package utils
+
+import (
+	"crypto/x509"
+	"encoding/pem"
+)
+
+func CheckHttps(pub string) (*x509.Certificate, error) {
+	skBlock, _ := pem.Decode([]byte(pub))
+	cert, err := x509.ParseCertificate(skBlock.Bytes)
+	return cert, err
+}

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 8
server/utils/cert_test.go


+ 54 - 54
server/utils/file.go

@@ -1,54 +1,54 @@
-package utils
-
-import (
-	"context"
-	"github.com/mholt/archiver/v4"
-	"os"
-	"path/filepath"
-	"strings"
-)
-
-func IsExist(path string) bool {
-	_, err := os.Stat(path)
-	if os.IsNotExist(err) {
-		return false
-	}
-	return true
-}
-
-func TarXz(dst string, src string) error {
-	src = filepath.Clean(src)
-	dst = filepath.Clean(dst)
-	if !strings.HasSuffix(src, string(os.PathSeparator)) {
-		src += string(os.PathSeparator)
-	}
-	files, err := archiver.FilesFromDisk(nil, map[string]string{
-		src: "",
-	})
-	if err != nil {
-		return err
-	}
-
-	out, err := os.Create(dst)
-	if err != nil {
-		return err
-	}
-	defer out.Close()
-	var compression archiver.Compression
-	if strings.HasSuffix(dst, "gz") {
-		compression = archiver.Gz{}
-	} else if strings.HasSuffix(dst, "xz") {
-		compression = archiver.Xz{}
-	} else {
-		compression = archiver.Gz{}
-	}
-	format := archiver.CompressedArchive{
-		Compression: compression,
-		Archival:    archiver.Tar{},
-	}
-	err = format.Archive(context.Background(), out, files)
-	if err != nil {
-		return err
-	}
-	return nil
-}
+package utils
+
+import (
+	"context"
+	"github.com/mholt/archiver/v4"
+	"os"
+	"path/filepath"
+	"strings"
+)
+
+func IsExist(path string) bool {
+	_, err := os.Stat(path)
+	if os.IsNotExist(err) {
+		return false
+	}
+	return true
+}
+
+func TarXz(dst string, src string) error {
+	src = filepath.Clean(src)
+	dst = filepath.Clean(dst)
+	if !strings.HasSuffix(src, string(os.PathSeparator)) {
+		src += string(os.PathSeparator)
+	}
+	files, err := archiver.FilesFromDisk(nil, map[string]string{
+		src: "",
+	})
+	if err != nil {
+		return err
+	}
+
+	out, err := os.Create(dst)
+	if err != nil {
+		return err
+	}
+	defer out.Close()
+	var compression archiver.Compression
+	if strings.HasSuffix(dst, "gz") {
+		compression = archiver.Gz{}
+	} else if strings.HasSuffix(dst, "xz") {
+		compression = archiver.Xz{}
+	} else {
+		compression = archiver.Gz{}
+	}
+	format := archiver.CompressedArchive{
+		Compression: compression,
+		Archival:    archiver.Tar{},
+	}
+	err = format.Archive(context.Background(), out, files)
+	if err != nil {
+		return err
+	}
+	return nil
+}

+ 19 - 19
server/utils/file_test.go

@@ -1,19 +1,19 @@
-package utils
-
-import (
-	"github.com/astaxie/beego/logs"
-	"testing"
-)
-
-func TestZipDir(t *testing.T) {
-	src := "../data/files/fcKFrcJamnjUTCI"
-	dst := "../data/files/fcKFrcJamnjUTCI.tar.xz"
-	err := TarXz(dst, src)
-
-	if err != nil {
-		logs.Error("zip fail", err)
-	} else {
-		logs.Info("zip ok")
-	}
-
-}
+package utils
+
+import (
+	"github.com/astaxie/beego/logs"
+	"testing"
+)
+
+func TestZipDir(t *testing.T) {
+	src := "../data/files/fcKFrcJamnjUTCI"
+	dst := "../data/files/fcKFrcJamnjUTCI.tar.xz"
+	err := TarXz(dst, src)
+
+	if err != nil {
+		logs.Error("zip fail", err)
+	} else {
+		logs.Info("zip ok")
+	}
+
+}

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 6
server/views/index.tpl


Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor