func init() { tree_event.ON(tree_event.ON_API_CONNECTED, func(e *tree_event.Event) { // tree_log.Info(log_from_node_api, "New API client connected -> ", string(e.Data)) }) tree_event.ON(tree_event.ON_API_DISCONNECTED, func(e *tree_event.Event) { // tree_log.Info(log_from_node_api, "New API client disconnected -> ", string(e.Data)) }) }
func (bs *BalancingService) SubscribeEvents() { tree_event.ON(tree_event.ON_DOCKER_INIT, func(e *tree_event.Event) { var err tree_lib.TreeError err.From = tree_lib.FROM_SUBSCRIBE_EVENTS if e.LocalVar == nil { tree_log.Info(err.From, "Containers list is nil during INIT event") return } for _, c := range e.LocalVar.([]docker.APIContainers) { if port, ok := bs.DockerImages[c.Image]; ok { var ci *docker.Container ci, err.Err = tree_docker.DockerClient.InspectContainer(c.ID) if !err.IsNull() { continue } cont_addr := Address{IP: ci.NetworkSettings.IPAddress, Port: port} err.Err = bs.AddDestination(cont_addr) if !err.IsNull() { return } containerAddressMap[c.ID] = cont_addr } } }) tree_event.ON(tree_event.ON_DOCKER_CONTAINER_START, func(e *tree_event.Event) { var err tree_lib.TreeError if e.LocalVar == nil { tree_log.Info(log_from_balancer, "Container Info is nil during container Start event") return } ci := e.LocalVar.(*tree_docker.ContainerInfo) if port, ok := bs.DockerImages[ci.Image]; ok { cont_addr := Address{IP: ci.InspectContainer.NetworkSettings.IPAddress, Port: port} err.Err = bs.AddDestination(cont_addr) if !err.IsNull() { return } containerAddressMap[ci.ID] = cont_addr } }) tree_event.ON(tree_event.ON_DOCKER_CONTAINER_STOP, func(e *tree_event.Event) { if e.LocalVar == nil { tree_log.Info(log_from_balancer, "Container ID is nil during container Stop event") return } cont_id := e.LocalVar.(string) if cont_addr, ok := containerAddressMap[cont_id]; ok { bs.DeleteDestination(cont_addr) delete(containerAddressMap, cont_id) bs.CheckForStopEvent() } }) }
func SendDockerCommand(cmd tree_docker.DockerCmd, node string, target []string, tag []string, group []string) { var err tree_lib.TreeError if !tree_api.API_INIT(node) { fmt.Println("Unable to init api client") fmt.Println("Exiting ...") return } err.From = tree_lib.FROM_SEND_DOCKER_COMMAND var ( api_cmd = tree_api.Command{} wait = make(chan bool) ) api_cmd.ID = tree_lib.RandomString(20) api_cmd.Data, err.Err = ffjson.Marshal(cmd) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } api_cmd.CommandType = tree_api.COMMAND_CONTAINER tree_event.ON(tree_event.ON_CHILD_CONNECTED, func(ev *tree_event.Event) { path := &tree_graph.Path{From: node, Nodes: target, Groups: group, Tags: tag} tree_api.SendCommand(&api_cmd, path, func(e *tree_event.Event, c tree_api.Command) bool { fmt.Println(string(c.Data)) fmt.Println(c.Ended) if c.Ended { return false } return true }) wait <- true }) <-wait }
func generate_tmp_db_dir() { tmp_db_dir = fmt.Sprintf("/tmp/%s", tree_lib.RandomFileName(15)) // Adding event on program exited or terminated, it will automatically remove out tmp database file tree_event.ON(tree_event.ON_PROGRAM_EXIT, func(e *tree_event.Event) { os.Remove(tmp_db_dir) }) }
func init() { tree_event.ON(tree_event.ON_RESTART_NODE, func(ev *tree_event.Event) { Restart() }) go func() { for { // After we have child information lets connect to them node_info.ChildsConnectionUpdate() time.Sleep(time.Millisecond * 500) } }() }
func NewBalancer(addr Address, algorithm string) (bs BalancingService, err error) { bs.DockerImages = make(map[string]int) bs.ChildServers = make(map[string]string) bs.Algorithm = algorithm bs.Address = addr err = bs.initLVS() if err != nil { return } // Deleting service before we will add it // In case if it is registered already DropService(addr.ToString()) err = bs.CreateService() if err != nil { return } // If Process is exiting then we need to delete this service before exit tree_event.ON(tree_event.ON_PROGRAM_EXIT, func(e *tree_event.Event) { bs.DropService() }) return }
func init() { var err tree_lib.TreeError err.From = tree_lib.FROM_INIT tree_db, err.Err = bolt.Open(DB_DIR, 0600, nil) if !err.IsNull() { tree_log.Error(log_from_db, " unable to open database", err.Error()) tree_db = nil os.Exit(1) // Without database we can't keep and share configurations, so program should be exited } // creating Buckets in database tree_db.Update(func(tx *bolt.Tx) (err error) { // Setting databases for _, d := range [][]byte{DB_NODE, DB_BALANCER, DB_RANDOM, DB_GROUP, DB_TAG, DB_RELATIONS, DB_REGISTRY, DB_EVENT} { _, err = tx.CreateBucketIfNotExists(d) if err != nil { return err } } return nil }) // Handling node change event tree_event.ON(tree_event.ON_UPDATE_NODE_INFO, func(e *tree_event.Event) { var ( info node_info.NodeInfo ev_info node_info.NodeInfo names []string data []byte mark bool ) err.Err = ffjson.Unmarshal(e.Data, &ev_info) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } info, err = GetNodeInfo(ev_info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } if len(info.Name) > 0 { err = DeleteNodeFromHisGroups(info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } err = DeleteNodeFromHisTags(info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } if len(ev_info.TreeIp) > 0 { info.TreeIp = ev_info.TreeIp mark = true } if ev_info.TreePort != -1 { info.TreePort = ev_info.TreePort mark = true } if len(ev_info.Childs[0]) > 0 { info.Childs = append(info.Childs, ev_info.Childs[0]) } if len(ev_info.Childs[1]) > 0 { if g, ok := tree_lib.ArrayContains(info.Childs, ev_info.Childs[1]); ok { info.Childs = info.Childs[:g+copy(info.Childs[g:], info.Childs[g+1:])] } } if len(ev_info.Groups[0]) > 0 { info.Groups = append(info.Groups, ev_info.Groups[0]) } if len(ev_info.Groups[1]) > 0 { if g, ok := tree_lib.ArrayContains(info.Groups, ev_info.Groups[1]); ok { info.Groups = info.Groups[:g+copy(info.Groups[g:], info.Groups[g+1:])] } } if len(ev_info.Tags[0]) > 0 { info.Tags = append(info.Tags, ev_info.Tags[0]) } if len(ev_info.Tags[1]) > 0 { if g, ok := tree_lib.ArrayContains(info.Tags, ev_info.Tags[1]); ok { info.Tags = info.Tags[:g+copy(info.Tags[g:], info.Tags[g+1:])] } } data, err.Err = ffjson.Marshal(info) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } err = Set(DB_NODE, []byte(ev_info.Name), data) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } names, err = ListNodeNames() if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } err = AddNodeToHisGroups(info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } err = AddNodeToHisTags(info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } for _, n := range names { err = SetRelations(n) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } } if node_info.CurrentNodeInfo.Name == ev_info.Name && mark { var e1 tree_event.Event e1.Name = tree_event.ON_RESTART_NODE tree_event.Trigger(&e1) } } else { err = Set(DB_NODE, []byte(ev_info.Name), e.Data) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } names, err = ListNodeNames() if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } err = AddNodeToHisGroups(ev_info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } err = AddNodeToHisTags(ev_info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } for _, n := range names { err = SetRelations(n) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } } if node_info.CurrentNodeInfo.Name == ev_info.Name { var e1 *tree_event.Event e1.Name = tree_event.ON_RESTART_NODE tree_event.Trigger(e1) } } }) // Closing database before program will be exited // Just in case if program exiting force or we don't want to make dead lock tree_event.ON(tree_event.ON_PROGRAM_EXIT, func(e *tree_event.Event) { CloseDB() }) }
func init() { // This event will be triggered from Node, when API client will send some command to implement tree_event.ON(tree_event.ON_API_COMMAND, func(ev *tree_event.Event) { var err tree_lib.TreeError err.From = tree_lib.FROM_INIT cmd := Command{} err.Err = ffjson.Unmarshal(ev.Data, &cmd) if !err.IsNull() { tree_log.Error(err.From, "unable to unmarshal event data as a command -> ", err.Error()) return } switch cmd.CommandType { case COMMAND_EXEC: { HandleExecCommand(ev, cmd) } case COMMAND_LIST: { HandleListCommand(ev, cmd) } case COMMAND_UPDATE: { HandleUpdateCommand(ev, cmd) } case COMMAND_CONTAINER: { HandleContainerCommand(ev, cmd) } case COMMAND_ADD_CUSTOM_EVENT: { HandleAddCustomEventHandlers(ev, cmd) } case COMMAND_TRIGGER_EVENT: { HandleTriggerCustomEvent(ev, cmd) } } }) // This event will be triggered from API client when Node will give callback for specific commands tree_event.ON(tree_event.ON_API_COMMAND_CALLBACK, func(ev *tree_event.Event) { var err tree_lib.TreeError err.From = tree_lib.FROM_INIT cmd := Command{} err.Err = ffjson.Unmarshal(ev.Data, &cmd) if !err.IsNull() { tree_log.Error(err.From, "unable to unmarshal event data as a command -> ", err.Error()) return } if cb, ok := subscribed_command_callbacks[cmd.ID]; ok && cb.f != nil { if !cb.f(ev, cmd) { // TODO: Maybe we need mutex to lock deleting process delete(subscribed_command_callbacks, cmd.ID) if cb.c != nil { cb.c <- true // Ending wait chanel in send command } } } }) }
func SendEventTriggerCommand(cmd *cobra.Command, args []string) { var ( event_name string err tree_lib.TreeError node string targets []string target_groups []string target_tags []string ) err.From = tree_lib.FROM_SEND_COMMAND node, err.Err = cmd.Flags().GetString("node") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } targets, err.Err = cmd.Flags().GetStringSlice("target") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } target_groups, err.Err = cmd.Flags().GetStringSlice("group") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } target_tags, err.Err = cmd.Flags().GetStringSlice("tag") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } event_name, err.Err = cmd.Flags().GetString("event") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } if !tree_api.API_INIT(node) { fmt.Println("Unable to init api client") fmt.Println("Exiting ...") return } var ( api_cmd = tree_api.Command{} wait_to_end = make(chan bool) ) api_cmd.Data = []byte(event_name) api_cmd.ID = tree_lib.RandomString(20) api_cmd.CommandType = tree_api.COMMAND_TRIGGER_EVENT tree_event.ON(tree_event.ON_CHILD_CONNECTED, func(ev *tree_event.Event) { path := &tree_graph.Path{From: node, Nodes: targets, Tags: target_tags, Groups: target_groups} tree_api.SendCommand(&api_cmd, path, func(e *tree_event.Event, c tree_api.Command) bool { fmt.Println(string(c.Data)) fmt.Println(c.Ended) // TODO: End coming faster than other messages FIX !!!! if c.Ended { return false } return true }) wait_to_end <- true }) <-wait_to_end }
func ListInfos(cmd *cobra.Command, args []string) { var ( err tree_lib.TreeError node string targets []string groups []string tags []string info tree_api.Info ) err.From = tree_lib.FROM_LIST_INFOS node, err.Err = cmd.Flags().GetString("node") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } targets, err.Err = cmd.Flags().GetStringSlice("target") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } groups, err.Err = cmd.Flags().GetStringSlice("group") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } tags, err.Err = cmd.Flags().GetStringSlice("tag") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } if !tree_api.API_INIT(node) { fmt.Println("Unable to init api client") fmt.Println("Exiting ...") return } var ( api_cmd = tree_api.Command{} wait = make(chan bool) ) info.Group = groups info.Target = targets info.Tag = tags api_cmd.Data, err.Err = ffjson.Marshal(info) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } api_cmd.ID = tree_lib.RandomString(20) api_cmd.CommandType = tree_api.COMMAND_LIST tree_event.ON(tree_event.ON_CHILD_CONNECTED, func(ev *tree_event.Event) { path := &tree_graph.Path{From: node, Nodes: []string{node}} tree_api.SendCommand(&api_cmd, path, func(e *tree_event.Event, c tree_api.Command) bool { var ( err tree_lib.TreeError info = make(map[string]node_info.NodeInfo) ) err.Err = ffjson.Unmarshal(c.Data, &info) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return false } for _, a := range info { fmt.Println("name: ", a.Name, ", Adress: ", a.TreeIp, ":", a.TreePort, ", Value: ", a.Value) fmt.Println("groups:", a.Groups) fmt.Println("tags:", a.Tags) fmt.Println("childs", a.Childs) } return false }) wait <- true }) <-wait }
func SendAddEventHandlerCommand(cmd *cobra.Command, args []string) { var ( event_name string err tree_lib.TreeError handler custom_event.Handler node string targets []string target_groups []string target_tags []string ) err.From = tree_lib.FROM_SEND_COMMAND node, err.Err = cmd.Flags().GetString("node") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } targets, err.Err = cmd.Flags().GetStringSlice("target") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } target_groups, err.Err = cmd.Flags().GetStringSlice("group") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } target_tags, err.Err = cmd.Flags().GetStringSlice("tag") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } event_name, err.Err = cmd.Flags().GetString("event") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } handler.Handler, err.Err = cmd.Flags().GetString("handler") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } handler.IsFile, err.Err = cmd.Flags().GetBool("file") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } handler.ExecUser, err.Err = cmd.Flags().GetString("user") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } handler.Password, err.Err = cmd.Flags().GetString("pass") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } var ( api_cmd = tree_api.Command{} wait_to_end = make(chan bool) ) api_cmd.Data, err.Err = ffjson.Marshal(map[string]interface{}{ "name": event_name, "handlers": []custom_event.Handler{handler}, }) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } if !tree_api.API_INIT(node) { fmt.Println("Unable to init api client") fmt.Println("Exiting ...") return } api_cmd.ID = tree_lib.RandomString(20) api_cmd.CommandType = tree_api.COMMAND_ADD_CUSTOM_EVENT tree_event.ON(tree_event.ON_CHILD_CONNECTED, func(ev *tree_event.Event) { path := &tree_graph.Path{From: node, Nodes: targets, Tags: target_tags, Groups: target_groups} tree_api.SendCommand(&api_cmd, path, func(e *tree_event.Event, c tree_api.Command) bool { fmt.Println(string(c.Data)) fmt.Println(c.Ended) // TODO: End coming faster than other messages FIX !!!! if c.Ended { return false } return true }) wait_to_end <- true }) <-wait_to_end }
func UpdateInfo(cmd *cobra.Command, args []string) { var ( node string err tree_lib.TreeError target string ip string port int add_to_group string delete_from_group string add_to_tag string delete_from_tag string delete_child string add_child string info node_info.NodeInfo ) err.From = tree_lib.FROM_UPDATE_INFO node, err.Err = cmd.Flags().GetString("node") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } target, err.Err = cmd.Flags().GetString("target") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } ip, err.Err = cmd.Flags().GetString("ip") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } port, err.Err = cmd.Flags().GetInt("port") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } add_to_group, err.Err = cmd.Flags().GetString("add_group") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } delete_from_group, err.Err = cmd.Flags().GetString("delete_group") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } add_to_tag, err.Err = cmd.Flags().GetString("add_tag") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } delete_from_tag, err.Err = cmd.Flags().GetString("delete_tag") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } add_child, err.Err = cmd.Flags().GetString("add_child") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } delete_child, err.Err = cmd.Flags().GetString("delete_child") if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } if !tree_api.API_INIT(node) { fmt.Println("Unable to init api client") fmt.Println("Exiting ...") return } info.Name = target info.TreeIp = ip info.TreePort = port info.Childs = append(info.Childs, add_child, delete_child) info.Groups = append(info.Groups, add_to_group, delete_from_group) info.Tags = append(info.Tags, add_to_tag, delete_from_tag) var ( api_cmd = tree_api.Command{} wait = make(chan bool) ) api_cmd.ID = tree_lib.RandomString(20) api_cmd.Data, err.Err = ffjson.Marshal(info) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } api_cmd.CommandType = tree_api.COMMAND_UPDATE tree_event.ON(tree_event.ON_CHILD_CONNECTED, func(ev *tree_event.Event) { path := &tree_graph.Path{From: node, Nodes: []string{node}} tree_api.SendCommand(&api_cmd, path, func(e *tree_event.Event, c tree_api.Command) bool { return false }) wait <- true }) <-wait }