v1.0.0
This commit is contained in:
		
						commit
						e8e9fa1d4a
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
IPCenter
 | 
			
		||||
ipcenter
 | 
			
		||||
							
								
								
									
										28
									
								
								actives.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								actives.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
			
		||||
{
 | 
			
		||||
    "switch": {
 | 
			
		||||
        "192.168.6.100:8080": {
 | 
			
		||||
            "HostMap": {}
 | 
			
		||||
        },
 | 
			
		||||
        "192.168.6.100:8082": {
 | 
			
		||||
            "HostMap": {}
 | 
			
		||||
        },
 | 
			
		||||
        "192.168.6.100:8083": {
 | 
			
		||||
            "HostMap": {}
 | 
			
		||||
        },
 | 
			
		||||
        "192.168.6.100:8084": {
 | 
			
		||||
            "HostMap": {}
 | 
			
		||||
        },
 | 
			
		||||
        "192.168.6.100:8085": {
 | 
			
		||||
            "HostMap": {}
 | 
			
		||||
        },
 | 
			
		||||
        "192.168.6.100:8086": {
 | 
			
		||||
            "HostMap": {}
 | 
			
		||||
        },
 | 
			
		||||
        "192.168.6.100:8087": {
 | 
			
		||||
            "HostMap": {}
 | 
			
		||||
        },
 | 
			
		||||
        "192.168.6.100:8088": {
 | 
			
		||||
            "HostMap": {}
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								actives.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								actives.yaml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
switch:
 | 
			
		||||
  192.168.6.100:8080: ["10.10.10.70", "10.10.10.71"]
 | 
			
		||||
  192.168.6.100:8082: ["10.10.10.74", "10.10.10.75"]
 | 
			
		||||
  192.168.6.100:8083: ["10.10.10.76", "10.10.10.77"]
 | 
			
		||||
  192.168.6.100:8085: ["10.10.10.80", "10.10.10.81"]
 | 
			
		||||
  192.168.6.100:8087: ["10.10.10.84", "10.10.10.85"]
 | 
			
		||||
  192.168.6.100:8088: ["10.10.10.86", "10.10.10.87"]
 | 
			
		||||
  192.168.6.100:8091: ["10.10.10.92", "10.10.10.93"]
 | 
			
		||||
restart: 65
 | 
			
		||||
							
								
								
									
										60
									
								
								alertover.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								alertover.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,60 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"log"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/levigross/grequests"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// AlertOver 报警相关
 | 
			
		||||
type AlertOver struct {
 | 
			
		||||
	Collection sync.Map // k 是title v是时间戳 用于统计上次的发送时间, 发送题目不能重复
 | 
			
		||||
	Setting    map[string]string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetDefaultSetting 设置默认Setting
 | 
			
		||||
func (ao *AlertOver) SetDefaultSetting() {
 | 
			
		||||
	ao.Setting = map[string]string{
 | 
			
		||||
		"source":   "s-577f047d-763a-4f45-a652-475595dc",
 | 
			
		||||
		"receiver": "g-5b4ce1ea-7f6b-422a-9127-a9049c65",
 | 
			
		||||
		"priority": "1",
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ao *AlertOver) send(data map[string]string) {
 | 
			
		||||
	// 合并初始化设置
 | 
			
		||||
	for k, v := range ao.Setting {
 | 
			
		||||
		data[k] = v
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	resp, err := grequests.Post("https://api.alertover.com/v1/alert",
 | 
			
		||||
		&grequests.RequestOptions{Data: data})
 | 
			
		||||
 | 
			
		||||
	now := time.Now().Unix()
 | 
			
		||||
	ao.Collection.Store(data["title"], now)
 | 
			
		||||
 | 
			
		||||
	ErrorLog(err)
 | 
			
		||||
	log.Println(resp.String())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Alert 报警API
 | 
			
		||||
func (ao *AlertOver) Alert(title, content string) {
 | 
			
		||||
 | 
			
		||||
	data := map[string]string{
 | 
			
		||||
		"title":   title,
 | 
			
		||||
		"content": content,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	now := time.Now().Unix()
 | 
			
		||||
	if _t, ok := ao.Collection.Load(title); ok {
 | 
			
		||||
		lasttime := _t.(int64)
 | 
			
		||||
		if now-lasttime >= 600 {
 | 
			
		||||
			ao.send(data)
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		ao.Collection.Store(title, now)
 | 
			
		||||
		ao.send(data)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										158
									
								
								dip.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								dip.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,158 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"log"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"474420502.top/eson/requests"
 | 
			
		||||
	"gopkg.in/yaml.v2"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type DIPWorker struct {
 | 
			
		||||
	ForMatch map[string]*DIPGroup `yaml:"switch"`
 | 
			
		||||
	ForLoop  map[string]*DIPGroup
 | 
			
		||||
	Restart  int64 `yaml:"restart"`
 | 
			
		||||
	Mutex    *sync.Mutex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ShowGroupInfo 展示实时的 Group 信息动态
 | 
			
		||||
func (worker *DIPWorker) ShowGroupInfo() string {
 | 
			
		||||
 | 
			
		||||
	now := time.Now().Unix()
 | 
			
		||||
 | 
			
		||||
	content := ""
 | 
			
		||||
	for addr, group := range worker.ForLoop {
 | 
			
		||||
		content += addr + ": ["
 | 
			
		||||
		for _, dhost := range group.Group {
 | 
			
		||||
 | 
			
		||||
			overtimeLabel := ""
 | 
			
		||||
			if now-dhost.ActiveTime >= 150 {
 | 
			
		||||
				overtimeLabel = "<☠?>"
 | 
			
		||||
			}
 | 
			
		||||
			tm := time.Unix(dhost.ActiveTime, 0)
 | 
			
		||||
			tm.Format("2006-01-02 15:04:05") //2018-07-11 15:10:19
 | 
			
		||||
			content += dhost.Host + "(" + tm.Format("2006-01-02 15:04:05") + overtimeLabel + "),"
 | 
			
		||||
		}
 | 
			
		||||
		content = strings.TrimRight(content, ",") + "]\n"
 | 
			
		||||
	}
 | 
			
		||||
	content = strings.TrimRight(content, "\n")
 | 
			
		||||
	return content
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type DIPGroup struct {
 | 
			
		||||
	Group      map[string]*DHost // 原始参照
 | 
			
		||||
	Ready      map[string]*DHost
 | 
			
		||||
	IPTableNum string
 | 
			
		||||
	Current    *DHost
 | 
			
		||||
 | 
			
		||||
	Mutex *sync.Mutex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewDIPGroup() *DIPGroup {
 | 
			
		||||
	group := DIPGroup{}
 | 
			
		||||
	group.Group = make(map[string]*DHost)
 | 
			
		||||
	group.Ready = make(map[string]*DHost)
 | 
			
		||||
	group.Mutex = &sync.Mutex{}
 | 
			
		||||
	return &group
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (group *DIPGroup) Choose(addr string) {
 | 
			
		||||
	now := time.Now().Unix()
 | 
			
		||||
	for ip, dhost := range group.Ready {
 | 
			
		||||
		// 设置转换的iptable
 | 
			
		||||
		if group.Current == nil {
 | 
			
		||||
			group.Current = dhost
 | 
			
		||||
			group.Current.ActiveTime = now
 | 
			
		||||
			SetAddrForward(group.IPTableNum, addr, ip)
 | 
			
		||||
		} else {
 | 
			
		||||
			restartAddr := "http://" + group.Current.Host + ":8800/pppoe/restart"
 | 
			
		||||
			if _, err := requests.NewSession().Get(restartAddr).Execute(); err != nil {
 | 
			
		||||
				log.Println(err)
 | 
			
		||||
				// group.Current.ActiveTime += 12
 | 
			
		||||
			} else {
 | 
			
		||||
				group.Current = dhost
 | 
			
		||||
				group.Current.ActiveTime = now
 | 
			
		||||
				// log.Println("new set addr:", group.Current.Host, "restartAddr:", restartAddr, "resp", resp.Content())
 | 
			
		||||
				SetAddrForward(group.IPTableNum, addr, ip)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		delete(group.Ready, ip)
 | 
			
		||||
 | 
			
		||||
		break
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type DHost struct {
 | 
			
		||||
	Host       string
 | 
			
		||||
	ActiveTime int64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewDHost(host string) *DHost {
 | 
			
		||||
	dh := DHost{}
 | 
			
		||||
	dh.ActiveTime = time.Now().Unix()
 | 
			
		||||
	dh.Host = host
 | 
			
		||||
	return &dh
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (dh *DHost) OverTime(now int64) int64 {
 | 
			
		||||
	if now-dh.ActiveTime >= 150 {
 | 
			
		||||
		return now - dh.ActiveTime
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (dip *DIPWorker) UnmarshalYAML(unmarshal func(interface{}) error) error {
 | 
			
		||||
	var data map[string]interface{}
 | 
			
		||||
	if err := unmarshal(&data); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	log.Println(data["switch"])
 | 
			
		||||
	myswitch := data["switch"]
 | 
			
		||||
 | 
			
		||||
	dip.Restart = int64(data["restart"].(int))
 | 
			
		||||
 | 
			
		||||
	num := 1
 | 
			
		||||
	for k, v := range myswitch.(map[interface{}]interface{}) {
 | 
			
		||||
 | 
			
		||||
		group := NewDIPGroup()
 | 
			
		||||
 | 
			
		||||
		// sudo iptables -t nat -R IPSWITCH 1 -p icmp  -j DNAT --to 1.1.1.1:8885
 | 
			
		||||
		for _, host := range v.([]interface{}) {
 | 
			
		||||
			dhost := NewDHost(host.(string))
 | 
			
		||||
			group.Group[dhost.Host] = dhost
 | 
			
		||||
			dip.ForMatch[dhost.Host] = group
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		dip.ForLoop[k.(string)] = group
 | 
			
		||||
		group.IPTableNum = strconv.Itoa(num)
 | 
			
		||||
		num++
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewDipWorker 创建一个
 | 
			
		||||
func NewDipWorker(filename string) *DIPWorker {
 | 
			
		||||
	worker := DIPWorker{}
 | 
			
		||||
	worker.ForMatch = make(map[string]*DIPGroup)
 | 
			
		||||
	worker.ForLoop = make(map[string]*DIPGroup)
 | 
			
		||||
 | 
			
		||||
	worker.Mutex = &sync.Mutex{}
 | 
			
		||||
 | 
			
		||||
	data, err := ioutil.ReadFile(filename)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	err = yaml.Unmarshal(data, &worker)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &worker
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								main.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"log"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var passwd = "youmi"
 | 
			
		||||
 | 
			
		||||
// ErrorLog 错误打日志
 | 
			
		||||
func ErrorLog(err error) bool {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Println(err)
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ErrorPanic 错误打日志
 | 
			
		||||
func ErrorPanic(err error) {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	log.SetFlags(log.Llongfile | log.LstdFlags)
 | 
			
		||||
	swi := NewSwitch()
 | 
			
		||||
	swi.Run("0.0.0.0:3333", `10\.10\..+`)
 | 
			
		||||
	// swi.Run("0.0.0.0:3333", ``)
 | 
			
		||||
	log.Fatal()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										175
									
								
								switch.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								switch.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,175 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"log"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os/exec"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Switch 轮换IP相关类
 | 
			
		||||
type Switch struct {
 | 
			
		||||
	// config      map[string]interface{}
 | 
			
		||||
	// configMutex sync.Mutex
 | 
			
		||||
	ipregion   *regexp.Regexp
 | 
			
		||||
	lastShow   int64
 | 
			
		||||
	lastSwitch int64
 | 
			
		||||
 | 
			
		||||
	Worker *DIPWorker
 | 
			
		||||
	AO     *AlertOver
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetAddrForward 设置当前ip 转发的节点
 | 
			
		||||
func SetAddrForward(num, addr, ip string) {
 | 
			
		||||
	port := strings.Split(addr, ":")[1]
 | 
			
		||||
	cmd := exec.Command("/bin/sh", "-c", "sudo iptables -t nat -R IPSWITCH "+num+" -p tcp --dport "+port+" -j DNAT --to "+ip+":8885")
 | 
			
		||||
	err := cmd.Run()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSwitch 初始化默认
 | 
			
		||||
func NewSwitch() *Switch {
 | 
			
		||||
	swi := Switch{}
 | 
			
		||||
	swi.Worker = NewDipWorker("actives.yaml")
 | 
			
		||||
	swi.AO = &AlertOver{}
 | 
			
		||||
	swi.AO.SetDefaultSetting()
 | 
			
		||||
 | 
			
		||||
	log.Println(swi.Worker.ShowGroupInfo())
 | 
			
		||||
 | 
			
		||||
	http.HandleFunc("/ippool/switch/imactive", swi.imActive)
 | 
			
		||||
	http.HandleFunc("/ippool/switch/update", swi.updateActives)
 | 
			
		||||
	http.HandleFunc("/ippool/switch/actives", swi.switchActives)
 | 
			
		||||
 | 
			
		||||
	return &swi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Run addr 监听的地址addr
 | 
			
		||||
// 	   ipregion 匹配adsl的规则, 作为ping服务器并且控制网络转发的调度
 | 
			
		||||
func (swi *Switch) Run(addr string, ipregion string) {
 | 
			
		||||
	swi.ipregion = regexp.MustCompile(ipregion)
 | 
			
		||||
 | 
			
		||||
	cmd := exec.Command("/bin/sh", "-c", "sudo iptables -t nat -N IPSWITCH")
 | 
			
		||||
	cmd.Run()
 | 
			
		||||
 | 
			
		||||
	cmd = exec.Command("/bin/sh", "-c", "sudo iptables -t nat -F IPSWITCH")
 | 
			
		||||
	cmd.Run()
 | 
			
		||||
 | 
			
		||||
	for range swi.Worker.ForLoop {
 | 
			
		||||
		cmd := exec.Command("/bin/sh", "-c", "sudo iptables -t nat -A IPSWITCH  -p icmp -s 1.1.1.1  -j DNAT --to 1.1.1.1:8885")
 | 
			
		||||
		err := cmd.Run()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			panic(err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	http.ListenAndServe(addr, nil)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// timeToSwitch 计算是否到切换时间
 | 
			
		||||
func (swi *Switch) timeToSwitch(now int64) {
 | 
			
		||||
	for addr, group := range swi.Worker.ForLoop {
 | 
			
		||||
		if group.Current == nil {
 | 
			
		||||
			group.Choose(addr)
 | 
			
		||||
		} else {
 | 
			
		||||
			if now >= group.Current.ActiveTime+swi.Worker.Restart {
 | 
			
		||||
				// log.Println(now, group.Current.ActiveTime, swi.Worker.Restart)
 | 
			
		||||
				group.Choose(addr)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// checkInReady 签到的IP(vps的vpn节点IP))
 | 
			
		||||
func (swi *Switch) checkInReady(ip string, now int64) {
 | 
			
		||||
 | 
			
		||||
	if dipg, ok := swi.Worker.ForMatch[ip]; ok {
 | 
			
		||||
 | 
			
		||||
		dipg.Group[ip].ActiveTime = now
 | 
			
		||||
 | 
			
		||||
		if dipg.Current == nil {
 | 
			
		||||
			dhost := NewDHost(ip)
 | 
			
		||||
			dhost.ActiveTime = now
 | 
			
		||||
			dipg.Ready[ip] = dhost
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
			if dipg.Current.Host != ip {
 | 
			
		||||
				if v, ok := dipg.Ready[ip]; ok {
 | 
			
		||||
					v.ActiveTime = now
 | 
			
		||||
				} else {
 | 
			
		||||
					dhost := NewDHost(ip)
 | 
			
		||||
					dhost.ActiveTime = now
 | 
			
		||||
					dipg.Ready[ip] = dhost
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// imActive 子节点访问 证明自己是活跃
 | 
			
		||||
func (swi *Switch) imActive(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
 | 
			
		||||
	w.Write([]byte("ok"))
 | 
			
		||||
	ip := strings.Split(r.RemoteAddr, ":")[0]
 | 
			
		||||
	// log.Println(ip) // 后续可以把这些节点, 自动活跃与更新
 | 
			
		||||
 | 
			
		||||
	swi.Worker.Mutex.Lock()
 | 
			
		||||
	defer swi.Worker.Mutex.Unlock()
 | 
			
		||||
 | 
			
		||||
	now := time.Now().Unix()
 | 
			
		||||
 | 
			
		||||
	// 60秒show一次日志
 | 
			
		||||
	if now >= swi.lastShow+60 {
 | 
			
		||||
		swi.lastShow = now
 | 
			
		||||
		log.Println("\n" + swi.Worker.ShowGroupInfo())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 5秒一次检测
 | 
			
		||||
	if now >= swi.lastSwitch+5 {
 | 
			
		||||
		swi.lastSwitch = now
 | 
			
		||||
		swi.timeToSwitch(now)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	swi.checkInReady(ip, now)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// updateActives 更新最新配置
 | 
			
		||||
func (swi *Switch) updateActives(w http.ResponseWriter, req *http.Request) {
 | 
			
		||||
 | 
			
		||||
	swi.Worker.Mutex.Lock()
 | 
			
		||||
	defer swi.Worker.Mutex.Unlock()
 | 
			
		||||
 | 
			
		||||
	swi.Worker = NewDipWorker("actives.yaml")
 | 
			
		||||
	w.Write([]byte("update success!"))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (swi *Switch) switchActives(w http.ResponseWriter, req *http.Request) {
 | 
			
		||||
 | 
			
		||||
	swi.Worker.Mutex.Lock()
 | 
			
		||||
	defer swi.Worker.Mutex.Unlock()
 | 
			
		||||
 | 
			
		||||
	now := time.Now().Unix()
 | 
			
		||||
 | 
			
		||||
	var content []string
 | 
			
		||||
	for addr, group := range swi.Worker.ForLoop {
 | 
			
		||||
 | 
			
		||||
		isappend := int64(1)
 | 
			
		||||
		for _, dhost := range group.Group {
 | 
			
		||||
			isappend *= dhost.OverTime(now)
 | 
			
		||||
		}
 | 
			
		||||
		if isappend == 0 {
 | 
			
		||||
			content = append(content, addr)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	jdata, err := json.Marshal(content)
 | 
			
		||||
	ErrorLog(err)
 | 
			
		||||
	_, err = w.Write(jdata)
 | 
			
		||||
	ErrorLog(err)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								switch_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								switch_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestSwitchYaml(t *testing.T) {
 | 
			
		||||
	t.Error()
 | 
			
		||||
 | 
			
		||||
	swi := NewSwitch()
 | 
			
		||||
	if swi == nil {
 | 
			
		||||
		t.Error("swi is error")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user