Exemple #1
0
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))
	})
}
Exemple #2
0
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()
		}
	})
}
Exemple #3
0
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
}
Exemple #4
0
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)
	})
}
Exemple #5
0
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)
		}
	}()
}
Exemple #6
0
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
}
Exemple #7
0
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()
	})
}
Exemple #8
0
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
				}
			}
		}
	})
}
Exemple #9
0
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
}
Exemple #10
0
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
}
Exemple #11
0
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
}
Exemple #12
0
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
}