コード例 #1
0
ファイル: handle.go プロジェクト: y8y/OWL-v3
//数据包逻辑处理
func (this *handle) HandlerMessage(conn *tcpserver.Conn, data []byte) {
	defer func() {
		if r := recover(); r != nil {
			slog.Error("Recovered in HandlerMessage", r)
		}
	}()
	slog.Debug("receive data: %s|%s", PROTOCOLTYPE[data[0]], string(data[1:]))
	switch data[0] {
	case HOSTCONFIG: //get host config
		req := &HostConfigReq{}
		if err := json.Unmarshal(data[1:], &req); err != nil {
			slog.Error("HandlerMessage() Parse HostConfigReq error(%s), data(%s)", err.Error(), string(data[1:]))
			return
		}
		if len(req.UUID) == 0 {
			return
		}
		host, err := mysql.GetHostConfigByUUID(req.UUID)
		if err != nil {
			if err == sql.ErrNoRows {
				proxy := conn.GetLocalIp()
				if req.Proxy == proxy {
					req.Proxy = ""
				}
				err = mysql.CreateHost(req)
				if err != nil {
					slog.Error("add host failed uuid(%s) ip(%s) proxy(%s) error(%s) ", req.UUID, req.IP, req.Proxy, err.Error())
					return
				} else {
					slog.Info("add host uuid(%s) proxy(%s) ip(%s) host(%v)", req.UUID, req.Proxy, req.IP, host)
				}
			}
			slog.Error("get host config error uuid(%s) ip(%s) proxy(%s) error(%s)", req.UUID, req.IP, req.Proxy, err.Error())
			return
		}

		if err := mysql.UpdateHostInfo(req); err != nil {
			slog.Error("update host info error %s", req.IP)
		}
		host.Ip = req.IP
		resp, err := json.Marshal(host)
		if err != nil {
			slog.Error("marshal host error %s", err.Error())
			return
		}
		packet := NewPacket(HOSTCONFIGRESP, resp)
		if err := conn.AsyncWriteData(packet); err != nil {
			slog.Error("HandlerMessage() AsyncWriteData() error(%s)", err.Error())
		}

	case CLIENTVERSION: //获取当前最新版本
		version := mysql.GetVersion()
		if len(version) == 0 {
			return
		}
		vp := map[string]string{"version": version}
		resp, _ := json.Marshal(vp)
		packet := NewPacket(CLIENTVERSIONRESP, resp)
		if err := conn.AsyncWriteData(packet); err != nil {
			slog.Error("AsyncWriteData error %s", err.Error())
		}
	case SERIESDATA:
		sdata := &SeriesData{}
		if err := json.Unmarshal(data[1:], &sdata); err != nil {
			slog.Error("parse monior data error(%s) data(%s)", err.Error(), string(data))
			return
		}
		//添加指标
		if sdata.Flag == 1 {
			host, err := mysql.GetHostConfigByUUID(sdata.UUID)
			if err != nil {
				return
			}
			for _, s := range host.Services {
				if s.Name == sdata.ServiceName {
					item := &Item{Key: sdata.Metric, DT: "GAUGE"}
					if err := mysql.CreateItemByService(s, item); err != nil {
						slog.Error("create item error(%s)", err.Error())
					} else {
						slog.Info("create item done service(%v) item(%v)", s.Name, sdata)
					}
				}
			}
		}
		DataBuffer <- []byte(fmt.Sprintf("put %s.%s %v %v uuid=%s ip=%s", sdata.ServiceName, sdata.Metric, sdata.TimeStamp, sdata.Value, sdata.UUID, sdata.IP))
		if cfg.ENABLE_REDIS {
			RedisBuffer <- fmt.Sprintf(`{"ip":"%s","metric":"%s.%s","@timestamp":"%v","value":%v}`,
				sdata.IP, sdata.ServiceName, sdata.Metric, time.Unix(sdata.TimeStamp, 0).Format(time.RFC3339), sdata.Value)
		}
	case PORTDISCOVERYR:
		req := &PortDiscovery{}
		if err := json.Unmarshal(data[1:], &req); err != nil {
			slog.Error("HandlerMessage() Parse PortDiscovery error(%s), data(%s)", err.Error(), string(data[1:]))
			return
		}
		host, err := mysql.GetHostByUUID(req.UUID)
		if err != nil {
			return
		}
		for _, port := range req.Ports {
			if !mysql.PortIsExists(host.ID, port.Port) {
				if err := mysql.CreatePort(host.ID, port); err != nil {
					slog.Error("create host port error(%s), host(%#v), port(%#v)", err.Error(), host, port)
					continue
				}
				slog.Info("create port, host(%s|%s) port(%v)", host.UUID, host.Ip, port)
			} else {
				slog.Info("port exists host(%s|%s) port(%d)", host.UUID, host.Ip, port.Port)
			}
		}

	case GETDEVICES: //获取网络设备
		req := &ProxyReq{}
		if err := json.Unmarshal(data[1:], &req); err != nil {
			slog.Error("HandlerMessage() Parse GetDevicesReq error(%s), data(%s)", err.Error(), string(data[1:]))
			return
		}
		if len(req.Proxy) == 0 {
			return
		}
		devices, err := mysql.GetDeviceByProxy(req.Proxy)
		if err != nil {
			slog.Error("HandlerMessage() Parse GetDeviceByProxy error(%s), proxy(%s)", err.Error(), req.Proxy)
			return
		}
		if len(devices) == 0 {
			return
		}
		resp, err := json.Marshal(devices)
		if err != nil {
			slog.Error("HandlerMessage() Marshal devices error(%s), proxy(%s), devices(%#v)", err.Error(), req.Proxy, devices)
			return
		}
		if err := conn.AsyncWriteData(NewPacket(GETDEVICESRESP, resp)); err != nil {
			slog.Error("HandlerMessage() send devices error %s proxy(%s)", err.Error(), req.Proxy)
		} else {
			slog.Info("HandleMessage() send devices to proxy(%s) done.", req.Proxy)
		}

	case GETPORTS:
		req := &ProxyReq{}
		if err := json.Unmarshal(data[1:], &req); err != nil {
			slog.Error("HandlerMessage() Parse GetDevicesReq error(%s), data(%s)", err.Error(), string(data[1:]))
			return
		}
		if len(req.Proxy) == 0 {
			return
		}
		ports := mysql.GetPortsByProxy(req.Proxy)
		if len(ports) == 0 {
			slog.Info("GetPortsByProxy no ports %s", req.Proxy)
			return
		}
		resp, err := json.Marshal(ports)
		if err != nil {
			slog.Error("HandlerMessage() Marshal ports error(%s), proxy(%s) ports(%#v)", err.Error(), req.Proxy, ports)
			return
		}
		if err := conn.AsyncWriteData(NewPacket(GETPORTSRESP, resp)); err != nil {
			slog.Error("HandlerMessage() send ports error %s proxy(%s)", err.Error(), req.Proxy)
		} else {
			slog.Info("HandleMessage() send prots to proxy(%s) done.", req.Proxy)
		}
	case UPDATEPORTS:
		ports := make([]*Port, 0)
		if err := json.Unmarshal(data[1:], &ports); err != nil {
			slog.Error("HandlerMessage() Parse UPDATEPORTS error(%s), data(%s)", err.Error(), string(data[1:]))
			return
		}
		for _, port := range ports {
			if err := mysql.UpdatePortStatus(port); err != nil {
				slog.Error("update port status error(%s) port(%v)", err.Error(), port)
				continue
			}
			slog.Info("update port status done, port(%v)", port)
		}

	case UPDATEDEVICES:

		devices := make([]*NetDevice, 0)
		if err := json.Unmarshal(data[1:], &devices); err != nil {
			slog.Error("HandlerMessage() Parse UPDATEDEVICES error(%s), data(%s)", err.Error(), string(data[1:]))
			return
		}
		for _, device := range devices {
			for _, i := range device.DeviceInterfaces {
				name := strings.ToLower(i.Name)
				if strings.Contains(name, "vlan") ||
					strings.Contains(name, "aux") ||
					strings.Contains(name, "loop") ||
					strings.Contains(name, "null") {
					continue
				}
				if mysql.InterfaceExist(i, device) {
					mysql.UpdateInterfaces(device, i)
				} else {
					slog.Info("device %s have a new interface %s, insert to mysql", device.IpAddr, i.Name)
					if err := mysql.CreateInterface(i, device); err != nil {
						slog.Info("device %s interface %s insert to mysql error %s", device.IpAddr, i.Name, err)
						continue
					} else {
						slog.Info("device %s interface %s insert to mysql done", device.IpAddr, i.Name)
					}
				}
			}
		}

	case ASSESTDISCOVERY:
		assest := &AssestPacket{}
		if err := json.Unmarshal(data[1:], &assest); err != nil {
			slog.Error("HandlerMessage() Parse ASSESTDISCOVERY error(%s), data(%s)", err.Error(), string(data[1:]))
			return
		}
		host, err := mysql.GetHostByUUID(assest.UUID)
		if err != nil {
			slog.Error("HandlerMessage() ASSESTDISCOVERY get host by uuid error(%s) assest(%v)", err.Error(), assest)
			return
		}
		//有资产信息
		if host.AssestId != 0 {
			oldassest := mysql.GetAssestByID(host.AssestId)
			flag := 0
			if oldassest.SN != assest.SN {
				oldassest.SN = assest.SN
				flag = 1
			}
			if oldassest.Vender != assest.Vender {
				oldassest.Vender = assest.Vender
				flag = 1
			}
			if oldassest.Model != assest.Model {
				oldassest.Model = assest.Model
				flag = 1
			}
			if flag == 1 {
				if err := mysql.UpdateAssest(oldassest); err != nil {
					slog.Error("update assest error(%s) assest(%v)", err.Error(), oldassest)
					return
				}
			}
			for _, cpu := range assest.Cpus {
				if c, ok := oldassest.Cpus[cpu.Name]; ok {
					cpu.ID = c.ID
					mysql.UpdateCpu(cpu)

				} else {
					mysql.CreateCpu(oldassest.ID, cpu)
				}

			}
			for _, disk := range assest.Disks {
				if d, ok := oldassest.Disks[disk.Slot]; ok {
					disk.ID = d.ID
					mysql.UpdateDisk(disk)
				} else {
					mysql.CreateDisk(oldassest.ID, disk)
				}

			}
			for _, nic := range assest.Nics {
				if n, ok := oldassest.Nics[nic.Name]; ok {
					nic.ID = n.ID
					mysql.UpdateNic(nic)
				} else {
					mysql.CreateNic(oldassest.ID, nic)
				}

			}
			for _, memory := range assest.Memorys {
				if m, ok := oldassest.Memorys[memory.Locator]; ok {
					memory.ID = m.ID
					mysql.UpdateMemory(memory)
				} else {
					mysql.CreateMemory(oldassest.ID, memory)
				}
			}
			return
		}
		//创建资产
		id, err := mysql.CreateAssest(assest)
		if err != nil {
			slog.Error("add assest error(%s) assest(%v)", err.Error(), assest)
			return
		}
		if err := mysql.UpdateHostAssest(host.ID, id); err != nil {
			slog.Error("linked host and assest error (%s) host(%v) assest(%v)", err.Error(), host, assest)
			return
		}
		slog.Info("add assest done, assest(%v)", assest)
	case HOSTHB:
		p := HeartBeat{}
		if err := json.Unmarshal(data[1:], &p); err != nil {
			slog.Error("HandlerMessage() Parse HOSTHB error(%s), data(%s)", err.Error(), string(data[1:]))
			return
		}
		host, err := mysql.GetHostByUUID(p.UUID)
		if err != nil {
			slog.Error("HandlerMessage() GetHostByUUID() error message(%s)", err.Error())
			return
		}
		if err := mysql.UpdateHostLastCheck(host); err != nil {
			slog.Error("update host last_check eror host(%v) error(%s)", host, err.Error())
		} else {
			slog.Info("update host last_check, host(%s:%s)", host.UUID, host.Ip)
		}
	default:
		slog.Warn("unknown protocol type, ip:%s,  data %s", conn.RemoteAddr(), string(data))
	}
}
コード例 #2
0
ファイル: handle.go プロジェクト: y8y/OWL-v3
//数据包逻辑处理
func (this *handle) HandlerMessage(conn *tcpserver.Conn, data []byte) {
	defer func() {
		recover()
	}()
	log.Trace("receive data: %s|%s", PROTOCOLTYPE[data[0]], string(data[1:]))
	switch data[0] {
	case GETDEVICESRESP:
		devices := []*NetDevice{}
		err := json.Unmarshal(data[1:], &devices)
		if err != nil {
			log.Error("HandlerMessage() marshal netdevices error %s data:%s", err.Error(), string(data[1:]))
			return
		}
		for _, dev := range devices {
			if _, ok := devicemap[dev.ID]; ok {
				if dev.IpAddr != devicemap[dev.ID].IpAddr {
					log.Info("change device ipaddr old:%v new:%v", devicemap[dev.ID].IpAddr, dev.IpAddr)
					devicemap[dev.ID].IpAddr = dev.IpAddr
				}
				if dev.SnmpVersion != devicemap[dev.ID].SnmpVersion {
					log.Info("change device %v SnmpVersion old:%v new:%v", dev.IpAddr, devicemap[dev.ID].SnmpVersion, dev.SnmpVersion)
					devicemap[dev.ID].SnmpVersion = dev.SnmpVersion
				}
				if dev.SnmpCommunity != devicemap[dev.ID].SnmpCommunity {
					log.Info("change device %v SnmpCommunity old:%v new:%v", dev.IpAddr, devicemap[dev.ID].SnmpCommunity, dev.SnmpCommunity)
					devicemap[dev.ID].SnmpCommunity = dev.SnmpCommunity
				}
				if dev.SnmpPort != devicemap[dev.ID].SnmpPort {
					log.Info("change device %v SnmpPort old:%v new:%v", dev.IpAddr, devicemap[dev.ID].SnmpPort, dev.SnmpPort)
					devicemap[dev.ID].SnmpPort = dev.SnmpPort
				}
				if dev.UpdateInterval != devicemap[dev.ID].UpdateInterval {
					log.Info("change device %v UpdateInterval old:%v new:%v", dev.IpAddr, devicemap[dev.ID].UpdateInterval, dev.UpdateInterval)
					devicemap[dev.ID].UpdateInterval = dev.UpdateInterval
					devicemap[dev.ID].updateTicker = time.NewTicker(time.Second * time.Duration(dev.UpdateInterval))
				}
				if dev.CheckInterval != devicemap[dev.ID].CheckInterval {
					log.Info("change device %v CheckInterval old:%v new:%v", dev.IpAddr, devicemap[dev.ID].CheckInterval, dev.CheckInterval)
					devicemap[dev.ID].CheckInterval = dev.CheckInterval
					devicemap[dev.ID].checkTicker = time.NewTicker(time.Second * time.Duration(dev.CheckInterval))
				}
			} else {
				dev.stopChan = make(chan struct{})
				dev.updateTicker = time.NewTicker(time.Second * time.Duration(dev.UpdateInterval))
				dev.checkTicker = time.NewTicker(time.Second * time.Duration(dev.CheckInterval))
				go dev.Run()
				devicemap[dev.ID] = dev
			}
		}
		for _, dev := range devicemap {
			flag := -1
			for _, d := range devices {
				if dev.ID == d.ID {
					flag = 0
				}
			}
			if flag == -1 {
				dev.Stop()
				delete(devicemap, dev.ID)
			}
		}

	case GETPORTSRESP:
		ports := []*Port{}
		fmt.Println(string(data[1:]))
		err := json.Unmarshal(data[1:], &ports)
		if err != nil {
			log.Error("HandlerMessage() marshal ports error %s data:%s", err.Error(), string(data[1:]))
			return
		}
		nports := []*Port{}
		for _, port := range ports {
			if err := port.StatusCheck(); err != nil {
				if port.Status == 0 {
					port.Status = 1
					nports = append(nports, port)
				}
			} else {
				if port.Status == 1 {
					port.Status = 0
					nports = append(nports, port)
				}
			}
		}
		if len(nports) == 0 {
			return
		}
		resp, err := json.Marshal(nports)
		if err != nil {
			return
		}
		DataBuffer <- NewPacket(UPDATEPORTS, resp)

	case HOSTCONFIG:
		req := &HostConfigReq{}
		if err := json.Unmarshal(data[1:], &req); err != nil {
			log.Error("HandlerMessage() Parse HostConfigReq error(%s), data(%s)", err.Error(), string(data[1:]))
			return
		}
		if len(req.UUID) == 0 {
			return
		}
		if host, ok := hostmap[req.UUID]; ok {
			resp, err := json.Marshal(host)
			if err != nil {
				log.Error("marshal host error %s", err.Error())
				return
			}
			packet := NewPacket(HOSTCONFIGRESP, resp)
			conn.AsyncWriteData(packet)
		}
		buf := make([]byte, 4+len(data))
		binary.BigEndian.PutUint32(buf, uint32(len(data)))
		buf = append(buf[:4], data...)
		DataBuffer <- buf

	case HOSTCONFIGRESP:
		host := &Host{}
		if err := json.Unmarshal(data[1:], &host); err != nil {
			log.Error("HandlerMessage() Unmarshal() HOSTCONFIGRESP error %s data:%s", err.Error(), string(data[1:]))
			return
		}
		log.Info("update hostconfig %s:%s", host.Ip, host.UUID)
		hostmap[host.UUID] = host

	case CLIENTVERSIONRESP:
		var vp map[string]string
		if err := json.Unmarshal(data[1:], &vp); err != nil {
			fmt.Println("unmarshal error %s", err.Error())
			return
		}
		if v, ok := vp["version"]; ok {
			log.Info("update client version %s->%s", version, v)
			version = v
		}

	case CLIENTVERSION:
		if len(version) == 0 {
			return
		}
		vp := map[string]string{"version": version}
		resp, _ := json.Marshal(vp)
		packet := NewPacket(CLIENTVERSIONRESP, resp)
		if err := conn.AsyncWriteData(packet); err != nil {
			log.Error("HandlerMessage() AsyncWriteData() version packet error %s %s", err.Error(), conn.RemoteAddr())
			return
		}
	case SERIESDATA, PORTDISCOVERYR, HOSTHB, ASSESTDISCOVERY:
		buf := make([]byte, 4+len(data))
		binary.BigEndian.PutUint32(buf, uint32(len(data)))
		buf = append(buf[:4], data...)
		DataBuffer <- buf
	default:
		log.Warn("unkown protocol type:%d data %s", data[0], string(data[1:]))
	}
}