Exemple #1
0
func HandleTriggerCustomEvent(e *tree_event.Event, api_cmd Command) {
	var (
		out        = &WriterCallback{BufferMaxSize: 1024}
		event_name = string(api_cmd.Data)
		err        tree_lib.TreeError
		ev_data    []byte
	)
	err.From = tree_lib.FROM_TRIGGER_CUSTOM_EVENT
	out.OutCallback = func(data []byte, ended bool) {
		cb_cmd := api_cmd
		cb_cmd.Ended = ended
		cb_cmd.Data = data
		ev_data, err.Err = ffjson.Marshal(cb_cmd)
		if !err.IsNull() {
			tree_log.Error(err.From, err.Error())
			return
		}
		SendCommandCallback(e, ev_data)
	}
	defer out.End()
	err = custom_event.Trigger(event_name, out)
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
	}
}
func HandleContainerCommand(ev *tree_event.Event, cmd Command) {
	var (
		out        = &WriterCallback{BufferMaxSize: 1024}
		docker_cmd = tree_docker.DockerCmd{}
		err        tree_lib.TreeError
		ev_data    []byte
	)
	err.From = tree_lib.FROM_HANDLE_CONTAINER_COMMAND
	err.Err = ffjson.Unmarshal(cmd.Data, &docker_cmd)
	if !err.IsNull() {
		tree_log.Error(err.From, "unable to unmarshal command data as a docker command -> ", err.Error())
		return
	}
	out.OutCallback = func(data []byte, ended bool) {
		cb_cmd := cmd
		cb_cmd.Ended = ended
		cb_cmd.Data = data
		ev_data, err.Err = ffjson.Marshal(cb_cmd)
		if !err.IsNull() {
			tree_log.Error(err.From, err.Error())
			return
		}
		SendCommandCallback(ev, ev_data)
	}

	defer out.End()

	tree_docker.ContainerCommands(&docker_cmd, out)
}
Exemple #3
0
// Executing some commands using exec.Command functionality from Go in OS
func HandleExecCommand(e *tree_event.Event, api_cmd Command) {
	var (
		out         = &WriterCallback{BufferMaxSize: 1024}
		cmd_str     = string(api_cmd.Data)
		cmd_options = strings.Split(cmd_str, " ")
		cmd         = exec.Command(cmd_options[0], cmd_options[1:]...)
		err         tree_lib.TreeError
		ev_data     []byte
	)
	err.From = tree_lib.FROM_HANDLE_EXEC_COMMAND
	out.OutCallback = func(data []byte, ended bool) {
		cb_cmd := api_cmd
		cb_cmd.Ended = ended
		cb_cmd.Data = data
		ev_data, err.Err = ffjson.Marshal(cb_cmd)
		if !err.IsNull() {
			tree_log.Error(err.From, err.Error())
			return
		}
		SendCommandCallback(e, ev_data)
	}

	defer out.End()

	cmd.Stdout = out
	cmd.Stderr = out
	err.Err = cmd.Run()
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
	}
}
Exemple #4
0
// Init API node for connection to targets
func API_INIT(targets ...string) bool {
	var err tree_lib.TreeError
	err.From = tree_lib.FROM_API_INIT
	if len(targets) == 0 {
		tree_log.Error(err.From, "For running API client you need to specify target node(s) to connect")
		return false
	}
	for _, n := range targets {
		node_info.ChildsNodeInfo[n], err = tree_db.GetNodeInfo(n)
		if !err.IsNull() {
			tree_log.Error(err.From, fmt.Sprintf("Unable Getting target (%s) node info from Node database, ", n), err.Error())
			return false
		}
	}

	rand.Seed(time.Now().UnixNano())
	node_info.CurrentNodeInfo = node_info.NodeInfo{
		Name:   fmt.Sprintf("%s|%s", API_NAME_PREFIX, tree_lib.RandomString(10)),
		Childs: targets,
		// Getting next prime number based on Unix Timestamp nanoseconds and
		// TODO: Think about making this in a different way
		Value: tree_lib.NextPrimeNumber((1 * rand.Int63n(100)) + int64(100)),
	}

	node_info.CurrentNodeValue = big.NewInt(node_info.CurrentNodeInfo.Value)

	// Setting node values based on child list
	node_info.CalculateChildParentNodeValues()

	// After we have child information lets connect to them
	node_info.ChildsConnectionUpdate()

	return true
}
Exemple #5
0
func BuildCmdHandler(cmd *cobra.Command, args []string) {
	var (
		silent, force, multiple bool
		err                     error
	)

	silent, err = cmd.Flags().GetBool("silent")
	if err != nil {
		tree_log.Error(log_from_tree_build, "Unable to get 'silent' flag", err.Error())
		return
	}

	force, err = cmd.Flags().GetBool("force")
	if err != nil {
		tree_log.Error(log_from_tree_build, "Unable to get 'force' flag", err.Error())
		return
	}

	multiple, err = cmd.Flags().GetBool("multiple")
	if err != nil {
		tree_log.Error(log_from_tree_build, "Unable to get 'force' flag", err.Error())
		return
	}

	generate_tmp_db_dir()
	// Adding fake flag for not duplicating code, and calling 'config' command
	cmd.Flags().String("out", tmp_db_dir, "")
	fmt.Println("Dumping Database file for transfer -> ", tmp_db_dir)
	CompileConfig(cmd, args) // After this step we have config in GLOBAL_CONFIG  variable and db file for sending to nodes

	BuildTree(&GLOBAL_CONFIG, silent, force, multiple)
}
Exemple #6
0
func HandleDelete(cmd *cobra.Command, args []string) {
	var (
		node      string
		target    []string
		tag       []string
		group     []string
		container string
		err       tree_lib.TreeError
	)
	err.From = tree_lib.FROM_HANDLE_DELETE
	node, err.Err = cmd.Flags().GetString("node")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	target, err.Err = cmd.Flags().GetStringSlice("target")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	container, err.Err = cmd.Flags().GetString("container")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	var (
		docker_cmd = tree_docker.DockerCmd{}
	)
	docker_cmd.Content = make(map[string]string)
	docker_cmd.Command = tree_docker.COMMAND_DOCKER_CONTAINER_DELETE
	docker_cmd.Content["container"] = container
	SendDockerCommand(docker_cmd, node, target, tag, group)
}
Exemple #7
0
func ListenParent() (err tree_lib.TreeError) {
	var (
		addr *net.TCPAddr
		conn *net.TCPConn
	)
	err.From = tree_lib.FROM_LISTEN_PARENT
	// If port is not set, setting it to default 8888
	if node_info.CurrentNodeInfo.TreePort == 0 {
		node_info.CurrentNodeInfo.TreePort = 8888
	}

	addr, err.Err = net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", node_info.CurrentNodeInfo.TreeIp, node_info.CurrentNodeInfo.TreePort))
	if !err.IsNull() {
		tree_log.Error(err.From, "Network Listen function", err.Error())
		return
	}

	listener, err.Err = net.ListenTCP("tcp", addr)
	if !err.IsNull() {
		tree_log.Error(err.From, "Network Listen function", err.Error())
		return
	}

	for {
		conn, err.Err = listener.AcceptTCP()
		if !err.IsNull() {
			tree_log.Error(err.From, err.Error())
			return
		}

		// Handle Parent connection
		go handle_api_or_parent_connection(conn)
	}
	return
}
Exemple #8
0
func HandleNodeCommand(cmd *cobra.Command, args []string) {
	var (
		name string
		err  tree_lib.TreeError
	)
	err.From = tree_lib.FROM_HANDLE_NODE_COMMAND
	name, err.Err = cmd.Flags().GetString("set-name")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
	}

	// If we have set-name flag then we just setting current_node in database and exiting
	if len(name) > 0 {
		tree_db.Set(tree_db.DB_RANDOM, []byte("current_node"), []byte(name))
		return
	}
	daemon := false
	daemon, err.Err = cmd.Flags().GetBool("daemon")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}

	if daemon {
		cmd := exec.Command("/bin/sh", "-c", fmt.Sprintf("%s node > %s 2>&1 &", os.Args[0], tree_log.LogFile))
		err.Err = cmd.Run()
		if !err.IsNull() {
			log.Fatal(err.Err)
		}
		return
	}

	name, err.Err = cmd.Flags().GetString("name")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}

	if len(name) == 0 {
		current_node_byte, err := tree_db.Get(tree_db.DB_RANDOM, []byte("current_node"))
		if !err.IsNull() {
			tree_log.Error(err.From, "Getting current node name from Random database, ", err.Error())
			return
		}
		if len(current_node_byte) == 0 {
			fmt.Println("Name is important for the first time run")
			return
		}
	} else {
		err = tree_node.SetCurrentNode(name)
		if !err.IsNull() {
			tree_log.Error(err.From, err.Error())
			return
		}
	}

	tree_node.Start()
}
Exemple #9
0
func HandleAddCustomEventHandlers(e *tree_event.Event, api_cmd Command) {
	var (
		out          = &WriterCallback{BufferMaxSize: 1024}
		handler_data map[string]interface{}
		err          tree_lib.TreeError
		ev_data      []byte
	)
	err.From = tree_lib.FROM_ADD_CUSTOM_EVENT
	err.Err = ffjson.Unmarshal(api_cmd.Data, &handler_data)
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}

	out.OutCallback = func(data []byte, ended bool) {
		cb_cmd := api_cmd
		cb_cmd.Ended = ended
		cb_cmd.Data = data
		ev_data, err.Err = ffjson.Marshal(cb_cmd)
		if !err.IsNull() {
			tree_log.Error(err.From, err.Error())
			return
		}
		SendCommandCallback(e, ev_data)
	}
	defer out.End()

	event_name := handler_data["name"].(string)
	handles_interfaces := handler_data["handlers"].([]interface{})
	var (
		handles_interfaces_data []byte
		handlers                []custom_event.Handler
	)
	handles_interfaces_data, err.Err = ffjson.Marshal(handles_interfaces)
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}

	err.Err = ffjson.Unmarshal(handles_interfaces_data, &handlers)
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}

	err = custom_event.ON(event_name, handlers...)
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
	}
}
Exemple #10
0
func SendToConn(data []byte, conn *net.TCPConn, path *big.Int) {
	// making variable for combining send data
	var (
		err           tree_lib.TreeError
		path_len_data = make([]byte, 4)
		msg_len_data  = make([]byte, 4)
		path_data     = path.Bytes()
		path_len      = uint32(len(path_data))
		buf           = bytes.Buffer{}
	)

	err.From = tree_lib.FROM_SEND_TO_CONN

	binary.LittleEndian.PutUint32(path_len_data, path_len)
	binary.LittleEndian.PutUint32(msg_len_data, path_len+uint32(len(data))+uint32(4))

	buf.Write(msg_len_data)
	buf.Write(path_len_data)
	buf.Write(path_data)
	buf.Write(data)

	if conn != nil {
		_, err.Err = conn.Write(buf.Bytes())
		if !err.IsNull() {
			tree_log.Error(err.From, fmt.Sprintf("Error sending data to path [%s]", path.String()), err.Error())
		}
	}

	buf.Reset()
}
Exemple #11
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 #12
0
func HandleUpdateCommand(ev *tree_event.Event, cmd Command) {
	var (
		data Command
		info node_info.NodeInfo
		err  tree_lib.TreeError
	)
	err.From = tree_lib.FROM_HANDLE_UPDATE_COMMAND
	err.Err = ffjson.Unmarshal(ev.Data, &data)
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
	}
	err.Err = ffjson.Unmarshal(data.Data, &info)
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
	}
	UpdateNodeChange(info)
	SendCommandCallback(ev, ev.Data)
}
Exemple #13
0
func RestoreFromConfigDump(cmd *cobra.Command, args []string) {
	var (
		dump_file string
		err       tree_lib.TreeError
	)
	err.From = tree_lib.FROM_RESTORE_FROM_CONFIG_DUMP
	dump_file, err.Err = cmd.Flags().GetString("file")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}

	err = tree_db.LoadFromDumpPath(dump_file)
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
}
Exemple #14
0
func PathFiles(conf_type string, paths []string) ([]string, tree_lib.TreeError) {
	var (
		err_r     tree_lib.TreeError
		names     []string
		FileNames func(path string) (err tree_lib.TreeError)
	)
	err_r.From = tree_lib.FROM_PATH_FILES
	FileNames = func(path string) (err tree_lib.TreeError) {
		err.From = tree_lib.FROM_PATH_FILES
		files_in_dir, e := ioutil.ReadDir(path)
		err.Err = e
		if !err.IsNull() {
			tree_log.Error(err.From, err.Error())
			return
		}

		for _, a := range files_in_dir {
			if !a.IsDir() {
				if strings.Replace(filepath.Ext(a.Name())[0:], ".", "", 1) == conf_type {
					names = append(names, fmt.Sprintf("%s/%s", path, a.Name()))
				}
			} else {
				err = FileNames(fmt.Sprintf("%s/%s", path, a.Name()))
				if !err.IsNull() {
					tree_log.Error(err.From, err.Error())
					return
				}
			}
		}
		return
	}

	for _, a := range paths {
		if string([]rune(a)[len(a)-1]) == "/" {
			a = a[:len(a)-1]
		}
		err_r = FileNames(a)
		if !err_r.IsNull() {
			tree_log.Error(err_r.From, err_r.Error())
			return nil, err_r
		}
	}
	return names, err_r
}
Exemple #15
0
func SetParent(name string) bool {
	var err tree_lib.TreeError
	err.From = tree_lib.FROM_SET_PARENT
	node_info.ParentNodeInfo, err = tree_db.GetNodeInfo(name)
	if !err.IsNull() {
		tree_log.Error(err.From, "Getting parent node info from Node database, ", err.Error())
		return false
	}
	return true
}
Exemple #16
0
func HandleList(cmd *cobra.Command, args []string) {
	var (
		node   string
		target []string
		tag    []string
		group  []string
		err    tree_lib.TreeError
	)
	err.From = tree_lib.FROM_HANDLE_LIST
	node, err.Err = cmd.Flags().GetString("node")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	target, err.Err = cmd.Flags().GetStringSlice("target")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	tag, err.Err = cmd.Flags().GetStringSlice("tag")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	group, err.Err = cmd.Flags().GetStringSlice("group")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	var (
		docker_cmd = tree_docker.DockerCmd{}
	)
	docker_cmd.Content = make(map[string]string)
	if cmd.Parent().Name() == "container" {
		docker_cmd.Command = tree_docker.COMMAND_DOCKER_CONTAINER_LIST
	} else {
		docker_cmd.Command = tree_docker.COMMAND_DOCKER_IMAGE_LIST
	}
	docker_cmd.Content["all"] = "yes"
	SendDockerCommand(docker_cmd, node, target, tag, group)
}
Exemple #17
0
func node_init() {
	// Getting current node name
	current_node_byte, err := tree_db.Get(tree_db.DB_RANDOM, []byte("current_node"))
	err.From = tree_lib.FROM_NODE_INIT
	if !err.IsNull() {
		tree_log.Error(err.From, "Getting current node name from Random database, ", err.Error())
		return
	}
	current_node_name = string(current_node_byte)
	node_info.CurrentNodeInfo, err = tree_db.GetNodeInfo(current_node_name)
	if !err.IsNull() {
		tree_log.Error(err.From, "Getting current node info from Node database, ", err.Error())
		return
	}

	// Setting current Node Value field from string to big.Int
	node_info.CurrentNodeValue = nil // Setting to nil for garbage collection
	node_info.CurrentNodeValue = big.NewInt(node_info.CurrentNodeInfo.Value)

	for _, child := range node_info.CurrentNodeInfo.Childs {
		node_info.ChildsNodeInfo[child], err = tree_db.GetNodeInfo(child)
		if !err.IsNull() {
			tree_log.Error(err.From, fmt.Sprintf("Getting child (%s) node info from Node database, ", child), err.Error())
			return
		}
	}

	// Setting relations
	tree_db.SetRelations(current_node_name)

	node_info.ParentNodeInfo, err = tree_db.GetParentInfo(current_node_name)
	if !err.IsNull() {
		tree_log.Error(err.From, "Getting parent node info from Node database, ", err.Error())
		return
	}

	// Setting node values based on child list
	node_info.CalculateChildParentNodeValues()
}
Exemple #18
0
func TriggerFromData(data []byte) {
	var (
		e   = new(Event)
		err tree_lib.TreeError
	)
	err.From = tree_lib.FROM_TRIGGER_FROM_DATA
	err.Err = ffjson.Unmarshal(data, e)
	if !err.IsNull() {
		tree_log.Error(log_from_event, err.Error())
		return
	}
	Trigger(e)
}
Exemple #19
0
func UpdateNodeChange(info node_info.NodeInfo) {
	var (
		ev  = &tree_event.Event{}
		err tree_lib.TreeError
	)
	err.From = tree_lib.FROM_UPDATE_NODE_CHANGE
	ev.Data, err.Err = ffjson.Marshal(info)
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	path := &tree_graph.Path{From: node_info.CurrentNodeInfo.Name, Nodes: []string{"*"}}
	ev.Name = tree_event.ON_UPDATE_NODE_INFO
	tree_event.Trigger(ev)
	tree_event.Emit(ev, path)
}
Exemple #20
0
func HandleImageDelete(cmd *cobra.Command, args []string) {
	var (
		node   string
		target []string
		tag    []string
		group  []string
		force  bool
		image  string
		err    tree_lib.TreeError
	)
	err.From = tree_lib.FROM_HANDLE_IMAGE_DELETE
	node, err.Err = cmd.Flags().GetString("node")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	target, err.Err = cmd.Flags().GetStringSlice("target")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	tag, err.Err = cmd.Flags().GetStringSlice("tag")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	group, err.Err = cmd.Flags().GetStringSlice("group")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	image, err.Err = cmd.Flags().GetString("image")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	force, err.Err = cmd.Flags().GetBool("force")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	var (
		docker_cmd = tree_docker.DockerCmd{}
	)
	docker_cmd.Content = make(map[string]string)
	docker_cmd.Command = tree_docker.COMMAND_DOCKER_IMAGE_DELETE
	docker_cmd.Content["image"] = image
	if force {
		docker_cmd.Content["force"] = "yes"
	} else {
		docker_cmd.Content["force"] = "no"
	}
	SendDockerCommand(docker_cmd, node, target, tag, group)
}
Exemple #21
0
func InitBalancers() {
	err := tree_db.ForEach(tree_db.DB_BALANCER, func(k []byte, v []byte) error {
		var err error
		bc := tree_balancer.BalancerConfig{Name: string(k)}
		err = ffjson.Unmarshal(v, &bc)
		if err != nil {
			return err
		}
		// TODO: Maybe we need to collect balancer services in MAP or Array
		_, err = tree_balancer.NewBalancerFromConfig(bc)
		return err
	})
	err.From = tree_lib.FROM_INIT_BALANCER
	if !err.IsNull() {
		tree_log.Error(err.From, "Unable to Init Balancers", err.Error())
		return
	}
}
Exemple #22
0
func SendCommandCallback(e *tree_event.Event, data []byte) (err tree_lib.TreeError) {
	cb_ev := &tree_event.Event{}
	path := &tree_graph.Path{}
	cb_ev.Name = tree_event.ON_API_COMMAND_CALLBACK
	cb_ev.Data = data
	path.Nodes = []string{e.From}
	path.From = node_info.CurrentNodeInfo.Name
	_, err = path.CalculatePathToApi(big.NewInt(e.FromApi))
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}

	// If it comes from API, then we need multiply also with API's negative value
	/*if e.FromApi != 0 {
		p.Mul(p, big.NewInt(e.FromApi))
		p.Mul(p, big.NewInt(e.FromApi))
	}*/

	tree_event.Emit(cb_ev, path)
	return
}
Exemple #23
0
func CompileConfig(cmd *cobra.Command, args []string) {
	var (
		files         []string
		conf_type     string
		out_file      string
		paths         []string
		files_in_path []string
		err           tree_lib.TreeError
	)
	err.From = tree_lib.FROM_COMPILE_CONFIG
	files, err.Err = cmd.Flags().GetStringSlice("files")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}

	conf_type, err.Err = cmd.Flags().GetString("type")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}

	out_file, err.Err = cmd.Flags().GetString("out")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	if _, err.Err = os.Stat(out_file); err.Err == nil {
		err.Err = os.Remove(out_file)
		if !err.IsNull() {
			tree_log.Error(err.From, err.Error())
		}
	}

	paths, err.Err = cmd.Flags().GetStringSlice("path")
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	if len(paths) > 0 {
		files_in_path, err = PathFiles(conf_type, paths)
		if !err.IsNull() {
			tree_log.Error(err.From, err.Error())
			return
		}
		for _, a := range files_in_path {
			files = append(files, a)
		}
	}
	if len(files) > 0 {
		err = ParseFiles(conf_type, files...)
		if !err.IsNull() {
			tree_log.Error(err.From, err.Error())
			return
		}
	}

	DBFromConfig()
	err = tree_db.DumpDBPath(out_file)
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	// Deleting database dir from console part
	err.Err = os.RemoveAll(tree_db.DB_DIR)
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
	}
}
Exemple #24
0
func DBFromConfig() {
	var (
		err        tree_lib.TreeError
		prev_prime = int64(1)
	)
	err.From = tree_lib.FROM_DB_FROM_CONFIG

	for n, nf := range GLOBAL_CONFIG.TreeNode {
		nf.Value = tree_lib.NextPrimeNumber(prev_prime)
		prev_prime = nf.Value
		err = tree_db.SetNodeInfo(n, nf)
		if !err.IsNull() {
			tree_log.Error(err.From, err.Error())
		}
	}

	// After having All nodes information now we can set related things for every node
	for n, _ := range GLOBAL_CONFIG.TreeNode {
		// Setting relations for every Node
		err = tree_db.SetRelations(n)
		if !err.IsNull() {
			tree_log.Error(err.From, err.Error())
		}

		// Setting Groups with node lists in Group database
		err = tree_db.AddNodeToHisGroups(n)
		if !err.IsNull() {
			tree_log.Error(err.From, err.Error())
		}

		// Setting Tags with node lists in Group database
		err = tree_db.AddNodeToHisTags(n)
		if !err.IsNull() {
			tree_log.Error(err.From, err.Error())
		}
	}

	// Setting Balancers
	for b, b_conf := range GLOBAL_CONFIG.Balancer {
		var b_data []byte
		b_data, err.Err = ffjson.Marshal(b_conf)
		if !err.IsNull() {
			tree_log.Error(err.From, "Error encoding balancer config", b, " -> ", err.Error())
			continue
		}
		err = tree_db.Set(tree_db.DB_BALANCER, []byte(b), b_data)
		if !err.IsNull() {
			tree_log.Error(err.From, "Error setting balancer config", b, " -> ", err.Error())
		}
	}

	// Setting Registry
	for r, r_conf := range GLOBAL_CONFIG.Registry {
		var r_data []byte
		r_data, err.Err = ffjson.Marshal(r_conf)
		if !err.IsNull() {
			tree_log.Error(err.From, "Error encoding registry config", r, " -> ", err.Error())
			continue
		}
		err = tree_db.Set(tree_db.DB_REGISTRY, []byte(r), r_data)
		if !err.IsNull() {
			tree_log.Error(err.From, "Error setting registry config", r, " -> ", err.Error())
		}
	}
}
Exemple #25
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 #26
0
func handle_api_or_parent_connection(conn *net.TCPConn) {
	defer conn.Close() // Connection should be closed, after return this function
	var (
		err            tree_lib.TreeError
		msg_data       []byte
		info_data      []byte
		conn_name      string
		is_api         = false
		conn_node_info node_info.NodeInfo
		api_val        *big.Int
	)
	err.From = tree_lib.FROM_HANDLE_API_OR_PARENT_CONNECTION
	// Making basic handshake to check the API validation
	// Connected Parent receiving name of the child(current node) and checking is it valid or not
	// if it is valid name then parent sending his name as an answer
	// otherwise it sending CLOSE_CONNECTION_MARK and closing connection

	info_data, err.Err = ffjson.Marshal(node_info.CurrentNodeInfo)
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}

	_, err.Err = tree_lib.SendMessage(info_data, conn)
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}

	info_data, err = tree_lib.ReadMessage(conn)
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}

	conn_name = string(info_data)
	if conn_name == CLOSE_CONNECTION_MARK {
		tree_log.Info(err.From, "Connection closed by parent node. Bad tree network handshake ! ", "Parent Addr: ", conn.RemoteAddr().String())
		return
	}

	err.Err = ffjson.Unmarshal(info_data, &conn_node_info)
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}

	if strings.Contains(conn_node_info.Name, tree_api.API_NAME_PREFIX) {
		api_val = big.NewInt(conn_node_info.Value)
		api_connections[api_val] = conn
		is_api = true
	} else {
		// TODO: Think about conn_node_info if we need to more checking for parent node info
		parentConnection = conn
	}

	if is_api {
		tree_event.TriggerWithData(tree_event.ON_API_CONNECTED, info_data)
	} else {
		tree_event.TriggerWithData(tree_event.ON_PARENT_CONNECTED, info_data)
	}

	// Listening parent messages
	for {
		msg_data, err = tree_lib.ReadMessage(conn)
		if !err.IsNull() {
			tree_log.Error(err.From, " reading data from -> ", conn_name, " ", err.Error())
			break
		}

		// Handling message events
		handle_message(is_api, true, msg_data)
	}

	if is_api {
		api_connections[api_val] = nil
		delete(api_connections, api_val)
		tree_event.TriggerWithData(tree_event.ON_API_DISCONNECTED, info_data)
	} else {
		parentConnection = nil
		tree_event.TriggerWithData(tree_event.ON_PARENT_DISCONNECTED, info_data)
	}
}
Exemple #27
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 #28
0
func ChildConnect(name string) (err tree_lib.TreeError) {
	var (
		conn           *net.TCPConn
		curr_data      []byte
		ch_info_data   []byte
		conn_node_info node_info.NodeInfo
		msg            []byte
	)
	err.From = tree_lib.FROM_CHILD_CONNECT
	conn, err = TcpConnect(node_info.ChildsNodeInfo[name].TreeIp, node_info.ChildsNodeInfo[name].TreePort)
	if !err.IsNull() {
		tree_log.Error(err.From, " child_connect -> ", name, " ", err.Error())
		return
	}
	defer conn.Close()

	ch_info_data, err = tree_lib.ReadMessage(conn)
	if !err.IsNull() {
		tree_log.Error(err.From, " child handshake -> ", name, " ", err.Error())
		return
	}

	err.Err = ffjson.Unmarshal(ch_info_data, &conn_node_info)
	if !err.IsNull() {
		tree_log.Error(err.From, " child handshake -> ", name, " ", err.Error())
		return
	}

	// If name revieved from connection not same name as we have
	// Then we connected to wrong server, just returning
	// defer will close connection
	if conn_node_info.Name != name {
		tree_lib.SendMessage([]byte(CLOSE_CONNECTION_MARK), conn)
		return
	}

	curr_data, err.Err = ffjson.Marshal(node_info.CurrentNodeInfo)
	if !err.IsNull() {
		tree_log.Error(err.From, " child handshake -> ", name, " ", err.Error())
		return
	}

	_, err.Err = tree_lib.SendMessage(curr_data, conn)
	if !err.IsNull() {
		tree_log.Error(err.From, " child handshake sending current info to -> ", name, " ", err.Error())
		return
	}

	child_connections[name] = conn

	tree_event.TriggerWithData(tree_event.ON_CHILD_CONNECTED, ch_info_data)

	for {
		msg, err = tree_lib.ReadMessage(conn)
		if !err.IsNull() {
			tree_log.Error(err.From, " reading data from child -> ", name, " ", err.Error())
			break
		}

		handle_message(false, false, msg)
	}

	child_connections[name] = nil
	delete(child_connections, name)

	tree_event.TriggerWithData(tree_event.ON_CHILD_DISCONNECTED, ch_info_data)

	return
}
Exemple #29
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 #30
0
func HandleListCommand(ev *tree_event.Event, cmd Command) {
	var (
		info           = make(map[string]node_info.NodeInfo)
		data           []byte
		ev_data        Command
		nodes          []string
		nodes_in_group []string
		nodes_in_tag   []string
		err            tree_lib.TreeError
		infos          Info
	)
	err.From = tree_lib.FROM_HANDLE_LIST_COMMAND
	err.Err = ffjson.Unmarshal(ev.Data, &ev_data)
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	err.Err = ffjson.Unmarshal(ev_data.Data, &infos)
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	nodes = infos.Target
	for _, g := range infos.Group {
		nodes_in_group, err = tree_db.GetGroupNodes(g)
		if !err.IsNull() {
			tree_log.Error(err.From, err.Error())
			return
		}
		for _, n := range nodes_in_group {
			nodes = append(nodes, n)
		}
	}
	for _, t := range infos.Tag {
		nodes_in_tag, err = tree_db.GetNodesByTagName(t)
		if !err.IsNull() {
			tree_log.Error(err.From, "getting Tags", err.Error())
			return
		}
		for _, n := range nodes_in_tag {
			nodes = append(nodes, n)
		}
	}
	for _, n := range nodes {
		info[n], err = tree_db.GetNodeInfo(n)
		if !err.IsNull() {
			tree_log.Error(err.From, err.Error())
			return
		}
	}
	cb_cmd := cmd
	cb_cmd.Data, err.Err = ffjson.Marshal(info)
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}
	data, err.Err = ffjson.Marshal(cb_cmd)
	if !err.IsNull() {
		tree_log.Error(err.From, err.Error())
		return
	}

	SendCommandCallback(ev, data)
}