mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-01 01:35:06 +03:00 
			
		
		
		
	Admin socket and yggdrasilctl refactoring (#939)
				
					
				
			This commit is contained in:
		
							parent
							
								
									4f2abece81
								
							
						
					
					
						commit
						c6fe81b5d2
					
				
					 11 changed files with 401 additions and 470 deletions
				
			
		|  | @ -14,9 +14,9 @@ import ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type CmdLineEnv struct { | type CmdLineEnv struct { | ||||||
| 	args                 []string | 	args             []string | ||||||
| 	endpoint, server     string | 	endpoint, server string | ||||||
| 	injson, verbose, ver bool | 	injson, ver      bool | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func newCmdLineEnv() CmdLineEnv { | func newCmdLineEnv() CmdLineEnv { | ||||||
|  | @ -46,7 +46,6 @@ func (cmdLineEnv *CmdLineEnv) parseFlagsAndArgs() { | ||||||
| 
 | 
 | ||||||
| 	server := flag.String("endpoint", cmdLineEnv.endpoint, "Admin socket endpoint") | 	server := flag.String("endpoint", cmdLineEnv.endpoint, "Admin socket endpoint") | ||||||
| 	injson := flag.Bool("json", false, "Output in JSON format (as opposed to pretty-print)") | 	injson := flag.Bool("json", false, "Output in JSON format (as opposed to pretty-print)") | ||||||
| 	verbose := flag.Bool("v", false, "Verbose output (includes public keys)") |  | ||||||
| 	ver := flag.Bool("version", false, "Prints the version of this build") | 	ver := flag.Bool("version", false, "Prints the version of this build") | ||||||
| 
 | 
 | ||||||
| 	flag.Parse() | 	flag.Parse() | ||||||
|  | @ -54,7 +53,6 @@ func (cmdLineEnv *CmdLineEnv) parseFlagsAndArgs() { | ||||||
| 	cmdLineEnv.args = flag.Args() | 	cmdLineEnv.args = flag.Args() | ||||||
| 	cmdLineEnv.server = *server | 	cmdLineEnv.server = *server | ||||||
| 	cmdLineEnv.injson = *injson | 	cmdLineEnv.injson = *injson | ||||||
| 	cmdLineEnv.verbose = *verbose |  | ||||||
| 	cmdLineEnv.ver = *ver | 	cmdLineEnv.ver = *ver | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -10,15 +10,15 @@ import ( | ||||||
| 	"net" | 	"net" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"os" | 	"os" | ||||||
| 	"sort" |  | ||||||
| 	"strconv" |  | ||||||
| 	"strings" | 	"strings" | ||||||
|  | 	"time" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/olekukonko/tablewriter" | ||||||
|  | 	"github.com/yggdrasil-network/yggdrasil-go/src/admin" | ||||||
|  | 	"github.com/yggdrasil-network/yggdrasil-go/src/core" | ||||||
| 	"github.com/yggdrasil-network/yggdrasil-go/src/version" | 	"github.com/yggdrasil-network/yggdrasil-go/src/version" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type admin_info map[string]interface{} |  | ||||||
| 
 |  | ||||||
| func main() { | func main() { | ||||||
| 	// makes sure we can use defer and still return an error code to the OS | 	// makes sure we can use defer and still return an error code to the OS | ||||||
| 	os.Exit(run()) | 	os.Exit(run()) | ||||||
|  | @ -54,103 +54,13 @@ func run() int { | ||||||
| 
 | 
 | ||||||
| 	cmdLineEnv.setEndpoint(logger) | 	cmdLineEnv.setEndpoint(logger) | ||||||
| 
 | 
 | ||||||
| 	conn := connect(cmdLineEnv.endpoint, logger) |  | ||||||
| 	logger.Println("Connected") |  | ||||||
| 	defer conn.Close() |  | ||||||
| 
 |  | ||||||
| 	decoder := json.NewDecoder(conn) |  | ||||||
| 	encoder := json.NewEncoder(conn) |  | ||||||
| 	send := make(admin_info) |  | ||||||
| 	recv := make(admin_info) |  | ||||||
| 
 |  | ||||||
| 	for c, a := range cmdLineEnv.args { |  | ||||||
| 		if c == 0 { |  | ||||||
| 			if strings.HasPrefix(a, "-") { |  | ||||||
| 				logger.Printf("Ignoring flag %s as it should be specified before other parameters\n", a) |  | ||||||
| 				continue |  | ||||||
| 			} |  | ||||||
| 			logger.Printf("Sending request: %v\n", a) |  | ||||||
| 			send["request"] = a |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		tokens := strings.Split(a, "=") |  | ||||||
| 		if len(tokens) == 1 { |  | ||||||
| 			send[tokens[0]] = true |  | ||||||
| 		} else if len(tokens) > 2 { |  | ||||||
| 			send[tokens[0]] = strings.Join(tokens[1:], "=") |  | ||||||
| 		} else if len(tokens) == 2 { |  | ||||||
| 			if i, err := strconv.Atoi(tokens[1]); err == nil { |  | ||||||
| 				logger.Printf("Sending parameter %s: %d\n", tokens[0], i) |  | ||||||
| 				send[tokens[0]] = i |  | ||||||
| 			} else { |  | ||||||
| 				switch strings.ToLower(tokens[1]) { |  | ||||||
| 				case "true": |  | ||||||
| 					send[tokens[0]] = true |  | ||||||
| 				case "false": |  | ||||||
| 					send[tokens[0]] = false |  | ||||||
| 				default: |  | ||||||
| 					send[tokens[0]] = tokens[1] |  | ||||||
| 				} |  | ||||||
| 				logger.Printf("Sending parameter %s: %v\n", tokens[0], send[tokens[0]]) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if err := encoder.Encode(&send); err != nil { |  | ||||||
| 		panic(err) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	logger.Printf("Request sent") |  | ||||||
| 
 |  | ||||||
| 	if err := decoder.Decode(&recv); err == nil { |  | ||||||
| 		logger.Printf("Response received") |  | ||||||
| 		if recv["status"] == "error" { |  | ||||||
| 			if err, ok := recv["error"]; ok { |  | ||||||
| 				fmt.Println("Admin socket returned an error:", err) |  | ||||||
| 			} else { |  | ||||||
| 				fmt.Println("Admin socket returned an error but didn't specify any error text") |  | ||||||
| 			} |  | ||||||
| 			return 1 |  | ||||||
| 		} |  | ||||||
| 		if _, ok := recv["request"]; !ok { |  | ||||||
| 			fmt.Println("Missing request in response (malformed response?)") |  | ||||||
| 			return 1 |  | ||||||
| 		} |  | ||||||
| 		if _, ok := recv["response"]; !ok { |  | ||||||
| 			fmt.Println("Missing response body (malformed response?)") |  | ||||||
| 			return 1 |  | ||||||
| 		} |  | ||||||
| 		res := recv["response"].(map[string]interface{}) |  | ||||||
| 
 |  | ||||||
| 		if cmdLineEnv.injson { |  | ||||||
| 			if json, err := json.MarshalIndent(res, "", "  "); err == nil { |  | ||||||
| 				fmt.Println(string(json)) |  | ||||||
| 			} |  | ||||||
| 			return 0 |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		handleAll(recv, cmdLineEnv.verbose) |  | ||||||
| 	} else { |  | ||||||
| 		logger.Println("Error receiving response:", err) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if v, ok := recv["status"]; ok && v != "success" { |  | ||||||
| 		return 1 |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return 0 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func connect(endpoint string, logger *log.Logger) net.Conn { |  | ||||||
| 	var conn net.Conn | 	var conn net.Conn | ||||||
| 
 | 	u, err := url.Parse(cmdLineEnv.endpoint) | ||||||
| 	u, err := url.Parse(endpoint) |  | ||||||
| 
 |  | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		switch strings.ToLower(u.Scheme) { | 		switch strings.ToLower(u.Scheme) { | ||||||
| 		case "unix": | 		case "unix": | ||||||
| 			logger.Println("Connecting to UNIX socket", endpoint[7:]) | 			logger.Println("Connecting to UNIX socket", cmdLineEnv.endpoint[7:]) | ||||||
| 			conn, err = net.Dial("unix", endpoint[7:]) | 			conn, err = net.Dial("unix", cmdLineEnv.endpoint[7:]) | ||||||
| 		case "tcp": | 		case "tcp": | ||||||
| 			logger.Println("Connecting to TCP socket", u.Host) | 			logger.Println("Connecting to TCP socket", u.Host) | ||||||
| 			conn, err = net.Dial("tcp", u.Host) | 			conn, err = net.Dial("tcp", u.Host) | ||||||
|  | @ -160,298 +70,174 @@ func connect(endpoint string, logger *log.Logger) net.Conn { | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		logger.Println("Connecting to TCP socket", u.Host) | 		logger.Println("Connecting to TCP socket", u.Host) | ||||||
| 		conn, err = net.Dial("tcp", endpoint) | 		conn, err = net.Dial("tcp", cmdLineEnv.endpoint) | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		panic(err) | 		panic(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return conn | 	logger.Println("Connected") | ||||||
| } | 	defer conn.Close() | ||||||
| 
 | 
 | ||||||
| func handleAll(recv map[string]interface{}, verbose bool) { | 	decoder := json.NewDecoder(conn) | ||||||
| 	req := recv["request"].(map[string]interface{}) | 	encoder := json.NewEncoder(conn) | ||||||
| 	res := recv["response"].(map[string]interface{}) | 	send := &admin.AdminSocketRequest{} | ||||||
|  | 	recv := &admin.AdminSocketResponse{} | ||||||
| 
 | 
 | ||||||
| 	switch strings.ToLower(req["request"].(string)) { | 	for c, a := range cmdLineEnv.args { | ||||||
| 	case "dot": | 		if c == 0 { | ||||||
| 		handleDot(res) | 			if strings.HasPrefix(a, "-") { | ||||||
| 	case "list", "getpeers", "getswitchpeers", "getdht", "getsessions", "dhtping": | 				logger.Printf("Ignoring flag %s as it should be specified before other parameters\n", a) | ||||||
| 		handleVariousInfo(res, verbose) | 				continue | ||||||
| 	case "gettuntap", "settuntap": | 			} | ||||||
| 		handleGetAndSetTunTap(res) | 			logger.Printf("Sending request: %v\n", a) | ||||||
| 	case "getself": | 			send.Name = a | ||||||
| 		handleGetSelf(res, verbose) | 			continue | ||||||
| 	case "getswitchqueues": | 		} | ||||||
| 		handleGetSwitchQueues(res) | 		tokens := strings.SplitN(a, "=", 1) | ||||||
| 	case "addpeer", "removepeer", "addallowedencryptionpublickey", "removeallowedencryptionpublickey", "addsourcesubnet", "addroute", "removesourcesubnet", "removeroute": | 		switch { | ||||||
| 		handleAddsAndRemoves(res) | 		case len(tokens) == 1: | ||||||
| 	case "getallowedencryptionpublickeys": | 			panic("incomplete argument supplied") | ||||||
| 		handleGetAllowedEncryptionPublicKeys(res) | 		default: | ||||||
| 	case "getmulticastinterfaces": | 			send.Arguments[tokens[0]] = tokens[1] | ||||||
| 		handleGetMulticastInterfaces(res) | 		} | ||||||
| 	case "getsourcesubnets": | 	} | ||||||
| 		handleGetSourceSubnets(res) | 
 | ||||||
| 	case "getroutes": | 	if err := encoder.Encode(&send); err != nil { | ||||||
| 		handleGetRoutes(res) | 		panic(err) | ||||||
| 	case "settunnelrouting": | 	} | ||||||
| 		fallthrough | 	logger.Printf("Request sent") | ||||||
| 	case "gettunnelrouting": | 	if err := decoder.Decode(&recv); err != nil { | ||||||
| 		handleGetTunnelRouting(res) | 		panic(err) | ||||||
| 	default: | 	} | ||||||
| 		if json, err := json.MarshalIndent(recv["response"], "", "  "); err == nil { | 	if recv.Status == "error" { | ||||||
|  | 		if err := recv.Error; err != "" { | ||||||
|  | 			fmt.Println("Admin socket returned an error:", err) | ||||||
|  | 		} else { | ||||||
|  | 			fmt.Println("Admin socket returned an error but didn't specify any error text") | ||||||
|  | 		} | ||||||
|  | 		return 1 | ||||||
|  | 	} | ||||||
|  | 	if cmdLineEnv.injson { | ||||||
|  | 		if json, err := json.MarshalIndent(recv.Response, "", "  "); err == nil { | ||||||
| 			fmt.Println(string(json)) | 			fmt.Println(string(json)) | ||||||
| 		} | 		} | ||||||
|  | 		return 0 | ||||||
| 	} | 	} | ||||||
| } | 
 | ||||||
| 
 | 	table := tablewriter.NewWriter(os.Stdout) | ||||||
| func handleDot(res map[string]interface{}) { | 	table.SetAlignment(tablewriter.ALIGN_LEFT) | ||||||
| 	fmt.Println(res["dot"]) | 	table.SetAutoFormatHeaders(false) | ||||||
| } | 	table.SetCenterSeparator("") | ||||||
| 
 | 	table.SetColumnSeparator("") | ||||||
| func handleVariousInfo(res map[string]interface{}, verbose bool) { | 	table.SetRowSeparator("") | ||||||
| 	maxWidths := make(map[string]int) | 	table.SetHeaderLine(false) | ||||||
| 	var keyOrder []string | 	table.SetBorder(false) | ||||||
| 	keysOrdered := false | 	table.SetTablePadding("\t") // pad with tabs | ||||||
| 
 | 	table.SetNoWhiteSpace(true) | ||||||
| 	for _, tlv := range res { | 
 | ||||||
| 		for slk, slv := range tlv.(map[string]interface{}) { | 	switch strings.ToLower(recv.Request.Name) { | ||||||
| 			if !keysOrdered { | 	case "list": | ||||||
| 				for k := range slv.(map[string]interface{}) { | 		var resp admin.ListResponse | ||||||
| 					if !verbose { | 		if err := json.Unmarshal(recv.Response, &resp); err != nil { | ||||||
| 						if k == "box_pub_key" || k == "box_sig_key" || k == "nodeinfo" || k == "was_mtu_fixed" { | 			panic(err) | ||||||
| 							continue | 		} | ||||||
| 						} | 		table.SetHeader([]string{"Command", "Arguments"}) | ||||||
| 					} | 		for _, entry := range resp.List { | ||||||
| 					keyOrder = append(keyOrder, fmt.Sprint(k)) | 			table.Append([]string{entry.Command, strings.Join(entry.Fields, ", ")}) | ||||||
| 				} | 		} | ||||||
| 				sort.Strings(keyOrder) | 		table.Render() | ||||||
| 				keysOrdered = true | 
 | ||||||
| 			} | 	case "getself": | ||||||
| 			for k, v := range slv.(map[string]interface{}) { | 		var resp admin.GetSelfResponse | ||||||
| 				if len(fmt.Sprint(slk)) > maxWidths["key"] { | 		if err := json.Unmarshal(recv.Response, &resp); err != nil { | ||||||
| 					maxWidths["key"] = len(fmt.Sprint(slk)) | 			panic(err) | ||||||
| 				} | 		} | ||||||
| 				if len(fmt.Sprint(v)) > maxWidths[k] { | 		table.Append([]string{"Build name:", resp.BuildName}) | ||||||
| 					maxWidths[k] = len(fmt.Sprint(v)) | 		table.Append([]string{"Build version:", resp.BuildVersion}) | ||||||
| 					if maxWidths[k] < len(k) { | 		table.Append([]string{"IPv6 address:", resp.IPAddress}) | ||||||
| 						maxWidths[k] = len(k) | 		table.Append([]string{"IPv6 subnet:", resp.Subnet}) | ||||||
| 					} | 		table.Append([]string{"Coordinates:", fmt.Sprintf("%v", resp.Coords)}) | ||||||
| 				} | 		table.Append([]string{"Public key:", resp.PublicKey}) | ||||||
| 			} | 		table.Render() | ||||||
| 		} | 
 | ||||||
| 
 | 	case "getpeers": | ||||||
| 		if len(keyOrder) > 0 { | 		var resp admin.GetPeersResponse | ||||||
| 			fmt.Printf("%-"+fmt.Sprint(maxWidths["key"])+"s  ", "") | 		if err := json.Unmarshal(recv.Response, &resp); err != nil { | ||||||
| 			for _, v := range keyOrder { | 			panic(err) | ||||||
| 				fmt.Printf("%-"+fmt.Sprint(maxWidths[v])+"s  ", v) | 		} | ||||||
| 			} | 		table.SetHeader([]string{"Port", "Public Key", "IP Address", "Peering URI", "Uptime", "RX", "TX"}) | ||||||
| 			fmt.Println() | 		for _, peer := range resp.Peers { | ||||||
| 		} | 			table.Append([]string{ | ||||||
| 
 | 				fmt.Sprintf("%d", peer.Port), | ||||||
| 		for slk, slv := range tlv.(map[string]interface{}) { | 				peer.PublicKey, | ||||||
| 			fmt.Printf("%-"+fmt.Sprint(maxWidths["key"])+"s  ", slk) | 				peer.IPAddress, | ||||||
| 			for _, k := range keyOrder { | 				peer.Remote, | ||||||
| 				preformatted := slv.(map[string]interface{})[k] | 				(time.Duration(peer.Uptime) * time.Second).String(), | ||||||
| 				var formatted string | 				peer.RXBytes.String(), | ||||||
| 				switch k { | 				peer.TXBytes.String(), | ||||||
| 				case "bytes_sent", "bytes_recvd": | 			}) | ||||||
| 					formatted = fmt.Sprintf("%d", uint(preformatted.(float64))) | 		} | ||||||
| 				case "uptime", "last_seen": | 		table.Render() | ||||||
| 					seconds := uint(preformatted.(float64)) % 60 | 
 | ||||||
| 					minutes := uint(preformatted.(float64)/60) % 60 | 	case "getdht": | ||||||
| 					hours := uint(preformatted.(float64) / 60 / 60) | 		var resp admin.GetDHTResponse | ||||||
| 					formatted = fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) | 		if err := json.Unmarshal(recv.Response, &resp); err != nil { | ||||||
| 				default: | 			panic(err) | ||||||
| 					formatted = fmt.Sprint(preformatted) | 		} | ||||||
| 				} | 		table.SetHeader([]string{"Public Key", "IP Address", "Port", "Rest"}) | ||||||
| 				fmt.Printf("%-"+fmt.Sprint(maxWidths[k])+"s  ", formatted) | 		for _, dht := range resp.DHT { | ||||||
| 			} | 			table.Append([]string{ | ||||||
| 			fmt.Println() | 				dht.PublicKey, | ||||||
| 		} | 				dht.IPAddress, | ||||||
| 	} | 				fmt.Sprintf("%d", dht.Port), | ||||||
| } | 				fmt.Sprintf("%d", dht.Rest), | ||||||
| 
 | 			}) | ||||||
| func handleGetAndSetTunTap(res map[string]interface{}) { | 		} | ||||||
| 	for k, v := range res { | 		table.Render() | ||||||
| 		fmt.Println("Interface name:", k) | 
 | ||||||
| 		if mtu, ok := v.(map[string]interface{})["mtu"].(float64); ok { | 	case "getpaths": | ||||||
| 			fmt.Println("Interface MTU:", mtu) | 		var resp admin.GetPathsResponse | ||||||
| 		} | 		if err := json.Unmarshal(recv.Response, &resp); err != nil { | ||||||
| 		if tap_mode, ok := v.(map[string]interface{})["tap_mode"].(bool); ok { | 			panic(err) | ||||||
| 			fmt.Println("TAP mode:", tap_mode) | 		} | ||||||
| 		} | 		table.SetHeader([]string{"Public Key", "IP Address", "Path"}) | ||||||
| 	} | 		for _, p := range resp.Paths { | ||||||
| } | 			table.Append([]string{ | ||||||
| 
 | 				p.PublicKey, | ||||||
| func handleGetSelf(res map[string]interface{}, verbose bool) { | 				p.IPAddress, | ||||||
| 	for k, v := range res["self"].(map[string]interface{}) { | 				fmt.Sprintf("%v", p.Path), | ||||||
| 		if buildname, ok := v.(map[string]interface{})["build_name"].(string); ok && buildname != "unknown" { | 			}) | ||||||
| 			fmt.Println("Build name:", buildname) | 		} | ||||||
| 		} | 		table.Render() | ||||||
| 		if buildversion, ok := v.(map[string]interface{})["build_version"].(string); ok && buildversion != "unknown" { | 
 | ||||||
| 			fmt.Println("Build version:", buildversion) | 	case "getsessions": | ||||||
| 		} | 		var resp admin.GetSessionsResponse | ||||||
| 		fmt.Println("IPv6 address:", k) | 		if err := json.Unmarshal(recv.Response, &resp); err != nil { | ||||||
| 		if subnet, ok := v.(map[string]interface{})["subnet"].(string); ok { | 			panic(err) | ||||||
| 			fmt.Println("IPv6 subnet:", subnet) | 		} | ||||||
| 		} | 		table.SetHeader([]string{"Public Key", "IP Address"}) | ||||||
| 		if boxSigKey, ok := v.(map[string]interface{})["key"].(string); ok { | 		for _, p := range resp.Sessions { | ||||||
| 			fmt.Println("Public key:", boxSigKey) | 			table.Append([]string{ | ||||||
| 		} | 				p.PublicKey, | ||||||
| 		if coords, ok := v.(map[string]interface{})["coords"].([]interface{}); ok { | 				p.IPAddress, | ||||||
| 			fmt.Println("Coords:", coords) | 			}) | ||||||
| 		} | 		} | ||||||
| 		if verbose { | 		table.Render() | ||||||
| 			if nodeID, ok := v.(map[string]interface{})["node_id"].(string); ok { | 
 | ||||||
| 				fmt.Println("Node ID:", nodeID) | 	case "getnodeinfo": | ||||||
| 			} | 		var resp core.GetNodeInfoResponse | ||||||
| 			if boxPubKey, ok := v.(map[string]interface{})["box_pub_key"].(string); ok { | 		if err := json.Unmarshal(recv.Response, &resp); err != nil { | ||||||
| 				fmt.Println("Public encryption key:", boxPubKey) | 			panic(err) | ||||||
| 			} | 		} | ||||||
| 			if boxSigKey, ok := v.(map[string]interface{})["box_sig_key"].(string); ok { | 		for _, v := range resp { | ||||||
| 				fmt.Println("Public signing key:", boxSigKey) | 			fmt.Println(string(v)) | ||||||
| 			} | 			break | ||||||
| 		} | 		} | ||||||
| 	} | 
 | ||||||
| } | 	default: | ||||||
| 
 | 		panic("unknown response type: " + recv.Request.Name) | ||||||
| func handleGetSwitchQueues(res map[string]interface{}) { | 	} | ||||||
| 	maximumqueuesize := float64(4194304) | 
 | ||||||
| 	portqueues := make(map[float64]float64) | 	return 0 | ||||||
| 	portqueuesize := make(map[float64]float64) |  | ||||||
| 	portqueuepackets := make(map[float64]float64) |  | ||||||
| 	v := res["switchqueues"].(map[string]interface{}) |  | ||||||
| 	if queuecount, ok := v["queues_count"].(float64); ok { |  | ||||||
| 		fmt.Printf("Active queue count: %d queues\n", uint(queuecount)) |  | ||||||
| 	} |  | ||||||
| 	if queuesize, ok := v["queues_size"].(float64); ok { |  | ||||||
| 		fmt.Printf("Active queue size: %d bytes\n", uint(queuesize)) |  | ||||||
| 	} |  | ||||||
| 	if highestqueuecount, ok := v["highest_queues_count"].(float64); ok { |  | ||||||
| 		fmt.Printf("Highest queue count: %d queues\n", uint(highestqueuecount)) |  | ||||||
| 	} |  | ||||||
| 	if highestqueuesize, ok := v["highest_queues_size"].(float64); ok { |  | ||||||
| 		fmt.Printf("Highest queue size: %d bytes\n", uint(highestqueuesize)) |  | ||||||
| 	} |  | ||||||
| 	if m, ok := v["maximum_queues_size"].(float64); ok { |  | ||||||
| 		maximumqueuesize = m |  | ||||||
| 		fmt.Printf("Maximum queue size: %d bytes\n", uint(maximumqueuesize)) |  | ||||||
| 	} |  | ||||||
| 	if queues, ok := v["queues"].([]interface{}); ok { |  | ||||||
| 		if len(queues) != 0 { |  | ||||||
| 			fmt.Println("Active queues:") |  | ||||||
| 			for _, v := range queues { |  | ||||||
| 				queueport := v.(map[string]interface{})["queue_port"].(float64) |  | ||||||
| 				queuesize := v.(map[string]interface{})["queue_size"].(float64) |  | ||||||
| 				queuepackets := v.(map[string]interface{})["queue_packets"].(float64) |  | ||||||
| 				queueid := v.(map[string]interface{})["queue_id"].(string) |  | ||||||
| 				portqueues[queueport]++ |  | ||||||
| 				portqueuesize[queueport] += queuesize |  | ||||||
| 				portqueuepackets[queueport] += queuepackets |  | ||||||
| 				queuesizepercent := (100 / maximumqueuesize) * queuesize |  | ||||||
| 				fmt.Printf("- Switch port %d, Stream ID: %v, size: %d bytes (%d%% full), %d packets\n", |  | ||||||
| 					uint(queueport), []byte(queueid), uint(queuesize), |  | ||||||
| 					uint(queuesizepercent), uint(queuepackets)) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if len(portqueuesize) > 0 && len(portqueuepackets) > 0 { |  | ||||||
| 		fmt.Println("Aggregated statistics by switchport:") |  | ||||||
| 		for k, v := range portqueuesize { |  | ||||||
| 			queuesizepercent := (100 / (portqueues[k] * maximumqueuesize)) * v |  | ||||||
| 			fmt.Printf("- Switch port %d, size: %d bytes (%d%% full), %d packets\n", |  | ||||||
| 				uint(k), uint(v), uint(queuesizepercent), uint(portqueuepackets[k])) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func handleAddsAndRemoves(res map[string]interface{}) { |  | ||||||
| 	if _, ok := res["added"]; ok { |  | ||||||
| 		for _, v := range res["added"].([]interface{}) { |  | ||||||
| 			fmt.Println("Added:", fmt.Sprint(v)) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if _, ok := res["not_added"]; ok { |  | ||||||
| 		for _, v := range res["not_added"].([]interface{}) { |  | ||||||
| 			fmt.Println("Not added:", fmt.Sprint(v)) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if _, ok := res["removed"]; ok { |  | ||||||
| 		for _, v := range res["removed"].([]interface{}) { |  | ||||||
| 			fmt.Println("Removed:", fmt.Sprint(v)) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if _, ok := res["not_removed"]; ok { |  | ||||||
| 		for _, v := range res["not_removed"].([]interface{}) { |  | ||||||
| 			fmt.Println("Not removed:", fmt.Sprint(v)) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func handleGetAllowedEncryptionPublicKeys(res map[string]interface{}) { |  | ||||||
| 	if _, ok := res["allowed_box_pubs"]; !ok { |  | ||||||
| 		fmt.Println("All connections are allowed") |  | ||||||
| 	} else if res["allowed_box_pubs"] == nil { |  | ||||||
| 		fmt.Println("All connections are allowed") |  | ||||||
| 	} else { |  | ||||||
| 		fmt.Println("Connections are allowed only from the following public box keys:") |  | ||||||
| 		for _, v := range res["allowed_box_pubs"].([]interface{}) { |  | ||||||
| 			fmt.Println("-", v) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func handleGetMulticastInterfaces(res map[string]interface{}) { |  | ||||||
| 	if _, ok := res["multicast_interfaces"]; !ok { |  | ||||||
| 		fmt.Println("No multicast interfaces found") |  | ||||||
| 	} else if res["multicast_interfaces"] == nil { |  | ||||||
| 		fmt.Println("No multicast interfaces found") |  | ||||||
| 	} else { |  | ||||||
| 		fmt.Println("Multicast peer discovery is active on:") |  | ||||||
| 		for _, v := range res["multicast_interfaces"].([]interface{}) { |  | ||||||
| 			fmt.Println("-", v) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func handleGetSourceSubnets(res map[string]interface{}) { |  | ||||||
| 	if _, ok := res["source_subnets"]; !ok { |  | ||||||
| 		fmt.Println("No source subnets found") |  | ||||||
| 	} else if res["source_subnets"] == nil { |  | ||||||
| 		fmt.Println("No source subnets found") |  | ||||||
| 	} else { |  | ||||||
| 		fmt.Println("Source subnets:") |  | ||||||
| 		for _, v := range res["source_subnets"].([]interface{}) { |  | ||||||
| 			fmt.Println("-", v) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func handleGetRoutes(res map[string]interface{}) { |  | ||||||
| 	if routes, ok := res["routes"].(map[string]interface{}); !ok { |  | ||||||
| 		fmt.Println("No routes found") |  | ||||||
| 	} else { |  | ||||||
| 		if res["routes"] == nil || len(routes) == 0 { |  | ||||||
| 			fmt.Println("No routes found") |  | ||||||
| 		} else { |  | ||||||
| 			fmt.Println("Routes:") |  | ||||||
| 			for k, v := range routes { |  | ||||||
| 				if pv, ok := v.(string); ok { |  | ||||||
| 					fmt.Println("-", k, " via ", pv) |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func handleGetTunnelRouting(res map[string]interface{}) { |  | ||||||
| 	if enabled, ok := res["enabled"].(bool); !ok { |  | ||||||
| 		fmt.Println("Tunnel routing is disabled") |  | ||||||
| 	} else if !enabled { |  | ||||||
| 		fmt.Println("Tunnel routing is disabled") |  | ||||||
| 	} else { |  | ||||||
| 		fmt.Println("Tunnel routing is enabled") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										20
									
								
								go.mod
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								go.mod
									
										
									
									
									
								
							|  | @ -13,23 +13,27 @@ require ( | ||||||
| 	github.com/mitchellh/mapstructure v1.4.1 | 	github.com/mitchellh/mapstructure v1.4.1 | ||||||
| 	github.com/vishvananda/netlink v1.1.0 | 	github.com/vishvananda/netlink v1.1.0 | ||||||
| 	golang.org/x/mobile v0.0.0-20220722155234-aaac322e2105 | 	golang.org/x/mobile v0.0.0-20220722155234-aaac322e2105 | ||||||
| 	golang.org/x/net v0.0.0-20211101193420-4a448f8816b3 | 	golang.org/x/net v0.0.0-20220722155237-a158d28d115b | ||||||
| 	golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 | 	golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f | ||||||
| 	golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b | 	golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b | ||||||
| 	golang.zx2c4.com/wireguard v0.0.0-20211017052713-f87e87af0d9a | 	golang.zx2c4.com/wireguard v0.0.0-20211017052713-f87e87af0d9a | ||||||
| 	golang.zx2c4.com/wireguard/windows v0.4.12 | 	golang.zx2c4.com/wireguard/windows v0.4.12 | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | require ( | ||||||
|  | 	github.com/mattn/go-colorable v0.1.8 // indirect | ||||||
|  | 	github.com/rivo/uniseg v0.2.0 // indirect | ||||||
|  | 	golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect | ||||||
|  | 	golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect | ||||||
|  | 	golang.org/x/tools v0.1.12 // indirect | ||||||
|  | ) | ||||||
|  | 
 | ||||||
| require ( | require ( | ||||||
| 	github.com/VividCortex/ewma v1.2.0 // indirect | 	github.com/VividCortex/ewma v1.2.0 // indirect | ||||||
| 	github.com/fatih/color v1.12.0 // indirect | 	github.com/fatih/color v1.12.0 // indirect | ||||||
| 	github.com/mattn/go-colorable v0.1.8 // indirect |  | ||||||
| 	github.com/mattn/go-isatty v0.0.13 // indirect | 	github.com/mattn/go-isatty v0.0.13 // indirect | ||||||
| 	github.com/mattn/go-runewidth v0.0.13 // indirect | 	github.com/mattn/go-runewidth v0.0.13 // indirect | ||||||
| 	github.com/rivo/uniseg v0.2.0 // indirect | 	github.com/olekukonko/tablewriter v0.0.5 | ||||||
|  | 	github.com/onsi/gomega v1.20.2 | ||||||
| 	github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect | 	github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect | ||||||
| 	golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect |  | ||||||
| 	golang.org/x/mod v0.4.2 // indirect |  | ||||||
| 	golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098 // indirect |  | ||||||
| 	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
							
								
								
									
										114
									
								
								go.sum
									
										
									
									
									
								
							
							
						
						
									
										114
									
								
								go.sum
									
										
									
									
									
								
							|  | @ -8,15 +8,40 @@ github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1o | ||||||
| github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= | github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= | ||||||
| github.com/cheggaaa/pb/v3 v3.0.8 h1:bC8oemdChbke2FHIIGy9mn4DPJ2caZYQnfbRqwmdCoA= | github.com/cheggaaa/pb/v3 v3.0.8 h1:bC8oemdChbke2FHIIGy9mn4DPJ2caZYQnfbRqwmdCoA= | ||||||
| github.com/cheggaaa/pb/v3 v3.0.8/go.mod h1:UICbiLec/XO6Hw6k+BHEtHeQFzzBH4i2/qk/ow1EJTA= | github.com/cheggaaa/pb/v3 v3.0.8/go.mod h1:UICbiLec/XO6Hw6k+BHEtHeQFzzBH4i2/qk/ow1EJTA= | ||||||
|  | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= | ||||||
|  | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= | ||||||
|  | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= | ||||||
|  | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||||
|  | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||||
| github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= | github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= | ||||||
| github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= | github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= | ||||||
| github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= | github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= | ||||||
|  | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= | ||||||
|  | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= | ||||||
|  | github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= | ||||||
|  | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||||
|  | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= | ||||||
|  | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= | ||||||
|  | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= | ||||||
|  | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= | ||||||
|  | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= | ||||||
|  | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= | ||||||
|  | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= | ||||||
|  | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= | ||||||
| github.com/gologme/log v1.2.0 h1:Ya5Ip/KD6FX7uH0S31QO87nCCSucKtF44TLbTtO7V4c= | github.com/gologme/log v1.2.0 h1:Ya5Ip/KD6FX7uH0S31QO87nCCSucKtF44TLbTtO7V4c= | ||||||
| github.com/gologme/log v1.2.0/go.mod h1:gq31gQ8wEHkR+WekdWsqDuf8pXTUZA9BnnzTuPz1Y9U= | github.com/gologme/log v1.2.0/go.mod h1:gq31gQ8wEHkR+WekdWsqDuf8pXTUZA9BnnzTuPz1Y9U= | ||||||
|  | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||||
|  | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||||||
|  | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||||
|  | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||||
|  | github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= | ||||||
|  | github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= | ||||||
| github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= | github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= | ||||||
| github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= | github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= | ||||||
| github.com/hjson/hjson-go v3.1.0+incompatible h1:DY/9yE8ey8Zv22bY+mHV1uk2yRy0h8tKhZ77hEdi0Aw= | github.com/hjson/hjson-go v3.1.0+incompatible h1:DY/9yE8ey8Zv22bY+mHV1uk2yRy0h8tKhZ77hEdi0Aw= | ||||||
| github.com/hjson/hjson-go v3.1.0+incompatible/go.mod h1:qsetwF8NlsTsOTwZTApNlTCerV+b2GjYRRcIk4JMFio= | github.com/hjson/hjson-go v3.1.0+incompatible/go.mod h1:qsetwF8NlsTsOTwZTApNlTCerV+b2GjYRRcIk4JMFio= | ||||||
|  | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= | ||||||
|  | github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= | ||||||
| github.com/kardianos/minwinsvc v1.0.0 h1:+JfAi8IBJna0jY2dJGZqi7o15z13JelFIklJCAENALA= | github.com/kardianos/minwinsvc v1.0.0 h1:+JfAi8IBJna0jY2dJGZqi7o15z13JelFIklJCAENALA= | ||||||
| github.com/kardianos/minwinsvc v1.0.0/go.mod h1:Bgd0oc+D0Qo3bBytmNtyRKVlp85dAloLKhfxanPFFRc= | github.com/kardianos/minwinsvc v1.0.0/go.mod h1:Bgd0oc+D0Qo3bBytmNtyRKVlp85dAloLKhfxanPFFRc= | ||||||
| github.com/lxn/walk v0.0.0-20210112085537-c389da54e794/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= | github.com/lxn/walk v0.0.0-20210112085537-c389da54e794/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= | ||||||
|  | @ -26,23 +51,48 @@ github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope | ||||||
| github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= | ||||||
| github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= | github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA= | ||||||
| github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= | github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= | ||||||
|  | github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= | ||||||
| github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= | github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= | ||||||
| github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= | github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= | ||||||
| github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= | github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= | ||||||
| github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= | github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= | ||||||
| github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= | github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= | ||||||
|  | github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= | ||||||
|  | github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= | ||||||
|  | github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= | ||||||
|  | github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= | ||||||
|  | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= | ||||||
|  | github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= | ||||||
|  | github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= | ||||||
|  | github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= | ||||||
|  | github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= | ||||||
|  | github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= | ||||||
|  | github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= | ||||||
|  | github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= | ||||||
|  | github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= | ||||||
|  | github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= | ||||||
|  | github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= | ||||||
|  | github.com/onsi/gomega v1.20.2 h1:8uQq0zMgLEfa0vRrrBgaJF2gyW9Da9BmfGV+OyUzfkY= | ||||||
|  | github.com/onsi/gomega v1.20.2/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= | ||||||
|  | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||||||
| github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= | github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= | ||||||
| github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= | github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= | ||||||
| github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= | ||||||
|  | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||||
|  | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= | ||||||
| github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0= | github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0= | ||||||
| github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= | github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= | ||||||
| github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= | github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= | ||||||
| github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA= | github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA= | ||||||
| github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= | github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= | ||||||
|  | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||||
| github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= | github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= | ||||||
|  | github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= | ||||||
|  | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= | ||||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||||
| golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||||
| golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||||
|  | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||||
| golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= | golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= | ||||||
| golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= | ||||||
| golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | ||||||
|  | @ -50,59 +100,105 @@ golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9t | ||||||
| golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= | ||||||
| golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= | ||||||
| golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= | ||||||
| golang.org/x/mobile v0.0.0-20220112015953-858099ff7816 h1:jhDgkcu3yQ4tasBZ+1YwDmK7eFmuVf1w1k+NGGGxfmE= |  | ||||||
| golang.org/x/mobile v0.0.0-20220112015953-858099ff7816/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ= |  | ||||||
| golang.org/x/mobile v0.0.0-20220722155234-aaac322e2105 h1:3vUV5x5+3LfQbgk7paCM6INOaJG9xXQbn79xoNkwfIk= | golang.org/x/mobile v0.0.0-20220722155234-aaac322e2105 h1:3vUV5x5+3LfQbgk7paCM6INOaJG9xXQbn79xoNkwfIk= | ||||||
| golang.org/x/mobile v0.0.0-20220722155234-aaac322e2105/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ= | golang.org/x/mobile v0.0.0-20220722155234-aaac322e2105/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ= | ||||||
| golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= | ||||||
| golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | ||||||
| golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | ||||||
|  | golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= | ||||||
|  | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= | ||||||
|  | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= | ||||||
|  | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||||
| golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||||
| golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||||
| golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||||
|  | golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= | ||||||
|  | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= | ||||||
| golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||||||
|  | golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= | ||||||
| golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||||
| golang.org/x/net v0.0.0-20210927181540-4e4d966f7476/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | golang.org/x/net v0.0.0-20210927181540-4e4d966f7476/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||||
| golang.org/x/net v0.0.0-20211011170408-caeb26a5c8c0/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | golang.org/x/net v0.0.0-20211011170408-caeb26a5c8c0/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||||
| golang.org/x/net v0.0.0-20211101193420-4a448f8816b3 h1:VrJZAjbekhoRn7n5FBujY31gboH+iB3pdLxn3gE9FjU= | golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||||
| golang.org/x/net v0.0.0-20211101193420-4a448f8816b3/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= | ||||||
|  | golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= | ||||||
|  | golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= | ||||||
|  | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= | ||||||
|  | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
| golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
|  | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
| golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
|  | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
|  | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
| golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
| golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
|  | golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
|  | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
|  | golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
|  | golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
|  | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
|  | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
|  | golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
| golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
| golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
| golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
| golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
| golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc= | golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
| golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
|  | golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
|  | golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
|  | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
|  | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= | ||||||
|  | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||||
| golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||||
|  | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= | ||||||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||||
| golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||||
| golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||||
|  | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= | ||||||
| golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b h1:NXqSWXSRUSCaFuvitrWtU169I3876zRTalMRbfd6LL0= | golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b h1:NXqSWXSRUSCaFuvitrWtU169I3876zRTalMRbfd6LL0= | ||||||
| golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b/go.mod h1:EFNZuWvGYxIRUEX+K8UmCFwYmZjqcrnq15ZuVldZkZ0= | golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b/go.mod h1:EFNZuWvGYxIRUEX+K8UmCFwYmZjqcrnq15ZuVldZkZ0= | ||||||
| golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||||
| golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | ||||||
| golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||||||
|  | golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= | ||||||
| golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= | golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= | ||||||
| golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098 h1:YuekqPskqwCCPM79F1X5Dhv4ezTCj+Ki1oNwiafxkA0= |  | ||||||
| golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= | golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= | ||||||
|  | golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= | ||||||
|  | golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= | ||||||
|  | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= | ||||||
| golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||||
| golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||||
| golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||||
| golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||||
| golang.zx2c4.com/wireguard v0.0.0-20211012062646-82d2aa87aa62/go.mod h1:id8Oh3eCCmpj9uVGWVjsUAl6UPX5ysMLzu6QxJU2UOU= | golang.zx2c4.com/wireguard v0.0.0-20211012062646-82d2aa87aa62/go.mod h1:id8Oh3eCCmpj9uVGWVjsUAl6UPX5ysMLzu6QxJU2UOU= | ||||||
| golang.zx2c4.com/wireguard v0.0.0-20211017052713-f87e87af0d9a h1:tTbyylK9/D3u/wEP26Vx7L700UpY48nhioJWZM1vhZw= | golang.zx2c4.com/wireguard v0.0.0-20211017052713-f87e87af0d9a h1:tTbyylK9/D3u/wEP26Vx7L700UpY48nhioJWZM1vhZw= | ||||||
| golang.zx2c4.com/wireguard v0.0.0-20211017052713-f87e87af0d9a/go.mod h1:id8Oh3eCCmpj9uVGWVjsUAl6UPX5ysMLzu6QxJU2UOU= | golang.zx2c4.com/wireguard v0.0.0-20211017052713-f87e87af0d9a/go.mod h1:id8Oh3eCCmpj9uVGWVjsUAl6UPX5ysMLzu6QxJU2UOU= | ||||||
| golang.zx2c4.com/wireguard/windows v0.4.12 h1:CUmbdWKVNzTSsVb4yUAiEwL3KsabdJkEPdDjCHxBlhA= | golang.zx2c4.com/wireguard/windows v0.4.12 h1:CUmbdWKVNzTSsVb4yUAiEwL3KsabdJkEPdDjCHxBlhA= | ||||||
| golang.zx2c4.com/wireguard/windows v0.4.12/go.mod h1:PW4y+d9oY83XU9rRwRwrJDwEMuhVjMxu2gfD1cfzS7w= | golang.zx2c4.com/wireguard/windows v0.4.12/go.mod h1:PW4y+d9oY83XU9rRwRwrJDwEMuhVjMxu2gfD1cfzS7w= | ||||||
|  | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= | ||||||
|  | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= | ||||||
|  | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= | ||||||
|  | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= | ||||||
|  | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= | ||||||
|  | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= | ||||||
|  | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= | ||||||
|  | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= | ||||||
|  | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= | ||||||
|  | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||||
|  | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= | ||||||
|  | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= | ||||||
|  | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
|  | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
|  | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
|  | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= | ||||||
|  | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||||
|  |  | ||||||
|  | @ -7,6 +7,7 @@ import ( | ||||||
| 	"net" | 	"net" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"os" | 	"os" | ||||||
|  | 	"sort" | ||||||
| 
 | 
 | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
|  | @ -28,13 +29,17 @@ type AdminSocket struct { | ||||||
| 	done       chan struct{} | 	done       chan struct{} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | type AdminSocketRequest struct { | ||||||
|  | 	Name      string            `json:"request"` | ||||||
|  | 	Arguments map[string]string `json:"arguments,omitempty"` | ||||||
|  | 	KeepAlive bool              `json:"keepalive,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
| type AdminSocketResponse struct { | type AdminSocketResponse struct { | ||||||
| 	Status  string `json:"status"` | 	Status   string             `json:"status"` | ||||||
| 	Request struct { | 	Error    string             `json:"error,omitempty"` | ||||||
| 		Name      string `json:"request"` | 	Request  AdminSocketRequest `json:"request"` | ||||||
| 		KeepAlive bool   `json:"keepalive"` | 	Response json.RawMessage    `json:"response"` | ||||||
| 	} `json:"request"` |  | ||||||
| 	Response interface{} `json:"response"` |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type handler struct { | type handler struct { | ||||||
|  | @ -43,11 +48,12 @@ type handler struct { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type ListResponse struct { | type ListResponse struct { | ||||||
| 	List map[string]ListEntry `json:"list"` | 	List []ListEntry `json:"list"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type ListEntry struct { | type ListEntry struct { | ||||||
| 	Fields []string `json:"fields"` | 	Command string   `json:"command"` | ||||||
|  | 	Fields  []string `json:"fields,omitempty"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // AddHandler is called for each admin function to add the handler and help documentation to the API. | // AddHandler is called for each admin function to add the handler and help documentation to the API. | ||||||
|  | @ -73,14 +79,16 @@ func (a *AdminSocket) Init(c *core.Core, nc *config.NodeConfig, log *log.Logger, | ||||||
| 	a.done = make(chan struct{}) | 	a.done = make(chan struct{}) | ||||||
| 	close(a.done) // Start in a done / not-started state | 	close(a.done) // Start in a done / not-started state | ||||||
| 	_ = a.AddHandler("list", []string{}, func(_ json.RawMessage) (interface{}, error) { | 	_ = a.AddHandler("list", []string{}, func(_ json.RawMessage) (interface{}, error) { | ||||||
| 		res := &ListResponse{ | 		res := &ListResponse{} | ||||||
| 			List: map[string]ListEntry{}, |  | ||||||
| 		} |  | ||||||
| 		for name, handler := range a.handlers { | 		for name, handler := range a.handlers { | ||||||
| 			res.List[name] = ListEntry{ | 			res.List = append(res.List, ListEntry{ | ||||||
| 				Fields: handler.args, | 				Command: name, | ||||||
| 			} | 				Fields:  handler.args, | ||||||
|  | 			}) | ||||||
| 		} | 		} | ||||||
|  | 		sort.SliceStable(res.List, func(i, j int) bool { | ||||||
|  | 			return strings.Compare(res.List[i].Command, res.List[j].Command) < 0 | ||||||
|  | 		}) | ||||||
| 		return res, nil | 		return res, nil | ||||||
| 	}) | 	}) | ||||||
| 	return a.core.SetAdmin(a) | 	return a.core.SetAdmin(a) | ||||||
|  | @ -277,22 +285,28 @@ func (a *AdminSocket) handleRequest(conn net.Conn) { | ||||||
| 		if err = json.Unmarshal(buf, &resp.Request); err == nil { | 		if err = json.Unmarshal(buf, &resp.Request); err == nil { | ||||||
| 			if resp.Request.Name == "" { | 			if resp.Request.Name == "" { | ||||||
| 				resp.Status = "error" | 				resp.Status = "error" | ||||||
| 				resp.Response = &ErrorResponse{ | 				resp.Response, _ = json.Marshal(ErrorResponse{ | ||||||
| 					Error: "No request specified", | 					Error: "No request specified", | ||||||
| 				} | 				}) | ||||||
| 			} else if h, ok := a.handlers[strings.ToLower(resp.Request.Name)]; ok { | 			} else if h, ok := a.handlers[strings.ToLower(resp.Request.Name)]; ok { | ||||||
| 				resp.Response, err = h.handler(buf) | 				res, err := h.handler(buf) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					resp.Status = "error" | 					resp.Status = "error" | ||||||
| 					resp.Response = &ErrorResponse{ | 					resp.Response, _ = json.Marshal(ErrorResponse{ | ||||||
| 						Error: err.Error(), | 						Error: err.Error(), | ||||||
| 					} | 					}) | ||||||
|  | 				} | ||||||
|  | 				if resp.Response, err = json.Marshal(res); err != nil { | ||||||
|  | 					resp.Status = "error" | ||||||
|  | 					resp.Response, _ = json.Marshal(ErrorResponse{ | ||||||
|  | 						Error: err.Error(), | ||||||
|  | 					}) | ||||||
| 				} | 				} | ||||||
| 			} else { | 			} else { | ||||||
| 				resp.Status = "error" | 				resp.Status = "error" | ||||||
| 				resp.Response = &ErrorResponse{ | 				resp.Response, _ = json.Marshal(ErrorResponse{ | ||||||
| 					Error: fmt.Sprintf("Unknown action '%s', try 'list' for help", resp.Request.Name), | 					Error: fmt.Sprintf("Unknown action '%s', try 'list' for help", resp.Request.Name), | ||||||
| 				} | 				}) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		if err = encoder.Encode(resp); err != nil { | 		if err = encoder.Encode(resp); err != nil { | ||||||
|  | @ -305,3 +319,16 @@ func (a *AdminSocket) handleRequest(conn net.Conn) { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | type DataUnit uint64 | ||||||
|  | 
 | ||||||
|  | func (d DataUnit) String() string { | ||||||
|  | 	switch { | ||||||
|  | 	case d > 1024*1024*1024: | ||||||
|  | 		return fmt.Sprintf("%2.fgb", float64(d)/1024/1024/1024) | ||||||
|  | 	case d > 1024*1024: | ||||||
|  | 		return fmt.Sprintf("%2.fmb", float64(d)/1024/1024) | ||||||
|  | 	default: | ||||||
|  | 		return fmt.Sprintf("%2.fkb", float64(d)/1024) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -3,6 +3,8 @@ package admin | ||||||
| import ( | import ( | ||||||
| 	"encoding/hex" | 	"encoding/hex" | ||||||
| 	"net" | 	"net" | ||||||
|  | 	"sort" | ||||||
|  | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"github.com/yggdrasil-network/yggdrasil-go/src/address" | 	"github.com/yggdrasil-network/yggdrasil-go/src/address" | ||||||
| ) | ) | ||||||
|  | @ -10,25 +12,30 @@ import ( | ||||||
| type GetDHTRequest struct{} | type GetDHTRequest struct{} | ||||||
| 
 | 
 | ||||||
| type GetDHTResponse struct { | type GetDHTResponse struct { | ||||||
| 	DHT map[string]DHTEntry `json:"dht"` | 	DHT []DHTEntry `json:"dht"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type DHTEntry struct { | type DHTEntry struct { | ||||||
|  | 	IPAddress string `json:"address"` | ||||||
| 	PublicKey string `json:"key"` | 	PublicKey string `json:"key"` | ||||||
| 	Port      uint64 `json:"port"` | 	Port      uint64 `json:"port"` | ||||||
| 	Rest      uint64 `json:"rest"` | 	Rest      uint64 `json:"rest"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (a *AdminSocket) getDHTHandler(req *GetDHTRequest, res *GetDHTResponse) error { | func (a *AdminSocket) getDHTHandler(req *GetDHTRequest, res *GetDHTResponse) error { | ||||||
| 	res.DHT = map[string]DHTEntry{} | 	dht := a.core.GetDHT() | ||||||
| 	for _, d := range a.core.GetDHT() { | 	res.DHT = make([]DHTEntry, 0, len(dht)) | ||||||
|  | 	for _, d := range dht { | ||||||
| 		addr := address.AddrForKey(d.Key) | 		addr := address.AddrForKey(d.Key) | ||||||
| 		so := net.IP(addr[:]).String() | 		res.DHT = append(res.DHT, DHTEntry{ | ||||||
| 		res.DHT[so] = DHTEntry{ | 			IPAddress: net.IP(addr[:]).String(), | ||||||
| 			PublicKey: hex.EncodeToString(d.Key[:]), | 			PublicKey: hex.EncodeToString(d.Key[:]), | ||||||
| 			Port:      d.Port, | 			Port:      d.Port, | ||||||
| 			Rest:      d.Rest, | 			Rest:      d.Rest, | ||||||
| 		} | 		}) | ||||||
| 	} | 	} | ||||||
|  | 	sort.SliceStable(res.DHT, func(i, j int) bool { | ||||||
|  | 		return strings.Compare(res.DHT[i].PublicKey, res.DHT[j].PublicKey) < 0 | ||||||
|  | 	}) | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -3,6 +3,8 @@ package admin | ||||||
| import ( | import ( | ||||||
| 	"encoding/hex" | 	"encoding/hex" | ||||||
| 	"net" | 	"net" | ||||||
|  | 	"sort" | ||||||
|  | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"github.com/yggdrasil-network/yggdrasil-go/src/address" | 	"github.com/yggdrasil-network/yggdrasil-go/src/address" | ||||||
| ) | ) | ||||||
|  | @ -11,23 +13,28 @@ type GetPathsRequest struct { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type GetPathsResponse struct { | type GetPathsResponse struct { | ||||||
| 	Paths map[string]PathEntry `json:"paths"` | 	Paths []PathEntry `json:"paths"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type PathEntry struct { | type PathEntry struct { | ||||||
|  | 	IPAddress string   `json:"address"` | ||||||
| 	PublicKey string   `json:"key"` | 	PublicKey string   `json:"key"` | ||||||
| 	Path      []uint64 `json:"path"` | 	Path      []uint64 `json:"path"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (a *AdminSocket) getPathsHandler(req *GetPathsRequest, res *GetPathsResponse) error { | func (a *AdminSocket) getPathsHandler(req *GetPathsRequest, res *GetPathsResponse) error { | ||||||
| 	res.Paths = map[string]PathEntry{} | 	paths := a.core.GetPaths() | ||||||
| 	for _, p := range a.core.GetPaths() { | 	res.Paths = make([]PathEntry, 0, len(paths)) | ||||||
|  | 	for _, p := range paths { | ||||||
| 		addr := address.AddrForKey(p.Key) | 		addr := address.AddrForKey(p.Key) | ||||||
| 		so := net.IP(addr[:]).String() | 		res.Paths = append(res.Paths, PathEntry{ | ||||||
| 		res.Paths[so] = PathEntry{ | 			IPAddress: net.IP(addr[:]).String(), | ||||||
| 			PublicKey: hex.EncodeToString(p.Key), | 			PublicKey: hex.EncodeToString(p.Key), | ||||||
| 			Path:      p.Path, | 			Path:      p.Path, | ||||||
| 		} | 		}) | ||||||
| 	} | 	} | ||||||
|  | 	sort.SliceStable(res.Paths, func(i, j int) bool { | ||||||
|  | 		return strings.Compare(res.Paths[i].PublicKey, res.Paths[j].PublicKey) < 0 | ||||||
|  | 	}) | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ package admin | ||||||
| import ( | import ( | ||||||
| 	"encoding/hex" | 	"encoding/hex" | ||||||
| 	"net" | 	"net" | ||||||
|  | 	"sort" | ||||||
| 
 | 
 | ||||||
| 	"github.com/yggdrasil-network/yggdrasil-go/src/address" | 	"github.com/yggdrasil-network/yggdrasil-go/src/address" | ||||||
| ) | ) | ||||||
|  | @ -11,33 +12,38 @@ type GetPeersRequest struct { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type GetPeersResponse struct { | type GetPeersResponse struct { | ||||||
| 	Peers map[string]PeerEntry `json:"peers"` | 	Peers []PeerEntry `json:"peers"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type PeerEntry struct { | type PeerEntry struct { | ||||||
|  | 	IPAddress string   `json:"address"` | ||||||
| 	PublicKey string   `json:"key"` | 	PublicKey string   `json:"key"` | ||||||
| 	Port      uint64   `json:"port"` | 	Port      uint64   `json:"port"` | ||||||
| 	Coords    []uint64 `json:"coords"` | 	Coords    []uint64 `json:"coords"` | ||||||
| 	Remote    string   `json:"remote"` | 	Remote    string   `json:"remote"` | ||||||
| 	RXBytes   uint64   `json:"bytes_recvd"` | 	RXBytes   DataUnit `json:"bytes_recvd"` | ||||||
| 	TXBytes   uint64   `json:"bytes_sent"` | 	TXBytes   DataUnit `json:"bytes_sent"` | ||||||
| 	Uptime    float64  `json:"uptime"` | 	Uptime    float64  `json:"uptime"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (a *AdminSocket) getPeersHandler(req *GetPeersRequest, res *GetPeersResponse) error { | func (a *AdminSocket) getPeersHandler(req *GetPeersRequest, res *GetPeersResponse) error { | ||||||
| 	res.Peers = map[string]PeerEntry{} | 	peers := a.core.GetPeers() | ||||||
| 	for _, p := range a.core.GetPeers() { | 	res.Peers = make([]PeerEntry, 0, len(peers)) | ||||||
|  | 	for _, p := range peers { | ||||||
| 		addr := address.AddrForKey(p.Key) | 		addr := address.AddrForKey(p.Key) | ||||||
| 		so := net.IP(addr[:]).String() | 		res.Peers = append(res.Peers, PeerEntry{ | ||||||
| 		res.Peers[so] = PeerEntry{ | 			IPAddress: net.IP(addr[:]).String(), | ||||||
| 			PublicKey: hex.EncodeToString(p.Key), | 			PublicKey: hex.EncodeToString(p.Key), | ||||||
| 			Port:      p.Port, | 			Port:      p.Port, | ||||||
| 			Coords:    p.Coords, | 			Coords:    p.Coords, | ||||||
| 			Remote:    p.Remote, | 			Remote:    p.Remote, | ||||||
| 			RXBytes:   p.RXBytes, | 			RXBytes:   DataUnit(p.RXBytes), | ||||||
| 			TXBytes:   p.TXBytes, | 			TXBytes:   DataUnit(p.TXBytes), | ||||||
| 			Uptime:    p.Uptime.Seconds(), | 			Uptime:    p.Uptime.Seconds(), | ||||||
| 		} | 		}) | ||||||
| 	} | 	} | ||||||
|  | 	sort.Slice(res.Peers, func(i, j int) bool { | ||||||
|  | 		return res.Peers[i].Port < res.Peers[j].Port | ||||||
|  | 	}) | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -9,28 +9,22 @@ import ( | ||||||
| type GetSelfRequest struct{} | type GetSelfRequest struct{} | ||||||
| 
 | 
 | ||||||
| type GetSelfResponse struct { | type GetSelfResponse struct { | ||||||
| 	Self map[string]SelfEntry `json:"self"` |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type SelfEntry struct { |  | ||||||
| 	BuildName    string   `json:"build_name"` | 	BuildName    string   `json:"build_name"` | ||||||
| 	BuildVersion string   `json:"build_version"` | 	BuildVersion string   `json:"build_version"` | ||||||
| 	PublicKey    string   `json:"key"` | 	PublicKey    string   `json:"key"` | ||||||
|  | 	IPAddress    string   `json:"address"` | ||||||
| 	Coords       []uint64 `json:"coords"` | 	Coords       []uint64 `json:"coords"` | ||||||
| 	Subnet       string   `json:"subnet"` | 	Subnet       string   `json:"subnet"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (a *AdminSocket) getSelfHandler(req *GetSelfRequest, res *GetSelfResponse) error { | func (a *AdminSocket) getSelfHandler(req *GetSelfRequest, res *GetSelfResponse) error { | ||||||
| 	res.Self = make(map[string]SelfEntry) |  | ||||||
| 	self := a.core.GetSelf() | 	self := a.core.GetSelf() | ||||||
| 	addr := a.core.Address().String() |  | ||||||
| 	snet := a.core.Subnet() | 	snet := a.core.Subnet() | ||||||
| 	res.Self[addr] = SelfEntry{ | 	res.BuildName = version.BuildName() | ||||||
| 		BuildName:    version.BuildName(), | 	res.BuildVersion = version.BuildVersion() | ||||||
| 		BuildVersion: version.BuildVersion(), | 	res.PublicKey = hex.EncodeToString(self.Key[:]) | ||||||
| 		PublicKey:    hex.EncodeToString(self.Key[:]), | 	res.IPAddress = a.core.Address().String() | ||||||
| 		Subnet:       snet.String(), | 	res.Subnet = snet.String() | ||||||
| 		Coords:       self.Coords, | 	res.Coords = self.Coords | ||||||
| 	} |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -3,6 +3,8 @@ package admin | ||||||
| import ( | import ( | ||||||
| 	"encoding/hex" | 	"encoding/hex" | ||||||
| 	"net" | 	"net" | ||||||
|  | 	"sort" | ||||||
|  | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"github.com/yggdrasil-network/yggdrasil-go/src/address" | 	"github.com/yggdrasil-network/yggdrasil-go/src/address" | ||||||
| ) | ) | ||||||
|  | @ -10,21 +12,26 @@ import ( | ||||||
| type GetSessionsRequest struct{} | type GetSessionsRequest struct{} | ||||||
| 
 | 
 | ||||||
| type GetSessionsResponse struct { | type GetSessionsResponse struct { | ||||||
| 	Sessions map[string]SessionEntry `json:"sessions"` | 	Sessions []SessionEntry `json:"sessions"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type SessionEntry struct { | type SessionEntry struct { | ||||||
|  | 	IPAddress string `json:"address"` | ||||||
| 	PublicKey string `json:"key"` | 	PublicKey string `json:"key"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (a *AdminSocket) getSessionsHandler(req *GetSessionsRequest, res *GetSessionsResponse) error { | func (a *AdminSocket) getSessionsHandler(req *GetSessionsRequest, res *GetSessionsResponse) error { | ||||||
| 	res.Sessions = map[string]SessionEntry{} | 	sessions := a.core.GetSessions() | ||||||
| 	for _, s := range a.core.GetSessions() { | 	res.Sessions = make([]SessionEntry, 0, len(sessions)) | ||||||
|  | 	for _, s := range sessions { | ||||||
| 		addr := address.AddrForKey(s.Key) | 		addr := address.AddrForKey(s.Key) | ||||||
| 		so := net.IP(addr[:]).String() | 		res.Sessions = append(res.Sessions, SessionEntry{ | ||||||
| 		res.Sessions[so] = SessionEntry{ | 			IPAddress: net.IP(addr[:]).String(), | ||||||
| 			PublicKey: hex.EncodeToString(s.Key[:]), | 			PublicKey: hex.EncodeToString(s.Key[:]), | ||||||
| 		} | 		}) | ||||||
| 	} | 	} | ||||||
|  | 	sort.SliceStable(res.Sessions, func(i, j int) bool { | ||||||
|  | 		return strings.Compare(res.Sessions[i].PublicKey, res.Sessions[j].PublicKey) < 0 | ||||||
|  | 	}) | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -4,7 +4,6 @@ import ( | ||||||
| 	"encoding/hex" | 	"encoding/hex" | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"net" |  | ||||||
| 	"runtime" | 	"runtime" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
|  | @ -13,7 +12,7 @@ import ( | ||||||
| 	"github.com/Arceliar/phony" | 	"github.com/Arceliar/phony" | ||||||
| 
 | 
 | ||||||
| 	//"github.com/yggdrasil-network/yggdrasil-go/src/crypto" | 	//"github.com/yggdrasil-network/yggdrasil-go/src/crypto" | ||||||
| 	"github.com/yggdrasil-network/yggdrasil-go/src/address" | 
 | ||||||
| 	"github.com/yggdrasil-network/yggdrasil-go/src/version" | 	"github.com/yggdrasil-network/yggdrasil-go/src/version" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -154,7 +153,7 @@ func (m *nodeinfo) _sendRes(key keyArray) { | ||||||
| type GetNodeInfoRequest struct { | type GetNodeInfoRequest struct { | ||||||
| 	Key string `json:"key"` | 	Key string `json:"key"` | ||||||
| } | } | ||||||
| type GetNodeInfoResponse map[string]interface{} | type GetNodeInfoResponse map[string]json.RawMessage | ||||||
| 
 | 
 | ||||||
| func (m *nodeinfo) nodeInfoAdminHandler(in json.RawMessage) (interface{}, error) { | func (m *nodeinfo) nodeInfoAdminHandler(in json.RawMessage) (interface{}, error) { | ||||||
| 	var req GetNodeInfoRequest | 	var req GetNodeInfoRequest | ||||||
|  | @ -182,8 +181,8 @@ func (m *nodeinfo) nodeInfoAdminHandler(in json.RawMessage) (interface{}, error) | ||||||
| 		if err := msg.UnmarshalJSON(info); err != nil { | 		if err := msg.UnmarshalJSON(info); err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 		ip := net.IP(address.AddrForKey(kbs)[:]) | 		key := hex.EncodeToString(kbs[:]) | ||||||
| 		res := GetNodeInfoResponse{ip.String(): msg} | 		res := GetNodeInfoResponse{key: msg} | ||||||
| 		return res, nil | 		return res, nil | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Neil Alexander
						Neil Alexander