Adam Ierymenko 5 years ago
parent
commit
d1b780c7be

+ 43 - 0
go/cmd/zerotier/cli/addroot.go

@@ -13,6 +13,49 @@
 
 
 package cli
 package cli
 
 
+import (
+	"fmt"
+	"io/ioutil"
+	"net/url"
+	"os"
+	"strings"
+
+	"zerotier/pkg/zerotier"
+)
+
 // AddRoot CLI command
 // AddRoot CLI command
 func AddRoot(basePath, authToken string, args []string) {
 func AddRoot(basePath, authToken string, args []string) {
+	if len(args) == 0 {
+		Help()
+		os.Exit(0)
+	}
+
+	locData, err := ioutil.ReadFile(args[0])
+	if err != nil {
+		fmt.Printf("ERROR: unable to read locator: %s\n", err.Error())
+		os.Exit(1)
+	}
+	loc, err := zerotier.NewLocatorFromBytes(locData)
+	if err != nil {
+		fmt.Printf("ERROR: invalid locator in file '%s': %s\n", args[0], err.Error())
+		os.Exit(1)
+	}
+
+	var name string
+	if len(args) > 1 {
+		if len(args) > 2 {
+			Help()
+			os.Exit(1)
+		}
+		name = strings.TrimSpace(args[1])
+	}
+
+	var result zerotier.Root
+	apiPost(basePath, authToken, "/root/"+url.PathEscape(name), &zerotier.Root{
+		Name:    name,
+		Locator: loc,
+	}, &result)
+
+	fmt.Println(jsonDump(&result))
+	os.Exit(0)
 }
 }

+ 2 - 2
go/cmd/zerotier/cli/help.go

@@ -40,13 +40,13 @@ Commands:
   service                              Start in system service mode
   service                              Start in system service mode
   status                               Show ZeroTier service status and config
   status                               Show ZeroTier service status and config
   peers                                Show VL1 peers
   peers                                Show VL1 peers
-  roots                                Show VL1 root servers
+  roots                                Show configured VL1 root servers
   addroot <locator> [name]             Add a VL1 root
   addroot <locator> [name]             Add a VL1 root
   removeroot <name>                    Remove a VL1 root
   removeroot <name>                    Remove a VL1 root
   locator <command> [args]             Locator management commands
   locator <command> [args]             Locator management commands
     new <identity> <address> [...]     Create and sign a locator
     new <identity> <address> [...]     Create and sign a locator
     newdnskey                          Create a secure DNS name and secret
     newdnskey                          Create a secure DNS name and secret
-    getdns <key> <locator>             Create secure DNS TXT records
+    getdns <dns key> <locator>         Create secure DNS TXT records
   identity <command> [args]            Identity management commands
   identity <command> [args]            Identity management commands
     new [c25519|p384]                  Create new identity (including secret)
     new [c25519|p384]                  Create new identity (including secret)
     getpublic <identity>               Extract only public part of identity
     getpublic <identity>               Extract only public part of identity

+ 17 - 0
go/cmd/zerotier/cli/misc.go

@@ -38,6 +38,23 @@ func apiGet(basePath, authToken, urlPath string, result interface{}) {
 	}
 	}
 }
 }
 
 
+func apiPost(basePath, authToken, urlPath string, post, result interface{}) {
+	statusCode, err := zerotier.APIPost(basePath, zerotier.APISocketName, authToken, urlPath, post, result)
+	if err != nil {
+		fmt.Printf("FATAL: API response code %d: %s\n", statusCode, err.Error())
+		os.Exit(1)
+		return
+	}
+	if statusCode != http.StatusOK {
+		if statusCode == http.StatusUnauthorized {
+			fmt.Printf("FATAL: API response code %d: unauthorized (authorization token incorrect)\n", statusCode)
+		}
+		fmt.Printf("FATAL: API response code %d\n", statusCode)
+		os.Exit(1)
+		return
+	}
+}
+
 func enabledDisabled(f bool) string {
 func enabledDisabled(f bool) string {
 	if f {
 	if f {
 		return "ENABLED"
 		return "ENABLED"

+ 37 - 7
go/pkg/zerotier/api.go

@@ -74,8 +74,11 @@ func APIPost(basePath, socketName, authToken, queryPath string, post, result int
 	if err != nil {
 	if err != nil {
 		return http.StatusTeapot, err
 		return http.StatusTeapot, err
 	}
 	}
-	err = json.NewDecoder(resp.Body).Decode(result)
-	return resp.StatusCode, err
+	if result != nil {
+		err = json.NewDecoder(resp.Body).Decode(result)
+		return resp.StatusCode, err
+	}
+	return resp.StatusCode, nil
 }
 }
 
 
 // APIStatus is the object returned by API status inquiries
 // APIStatus is the object returned by API status inquiries
@@ -337,7 +340,21 @@ func createAPIServer(basePath string, node *Node) (*http.Server, error) {
 			}
 			}
 		}
 		}
 
 
-		if req.Method == http.MethodPost || req.Method == http.MethodPut {
+		if req.Method == http.MethodDelete {
+			if queriedID == 0 {
+				_ = apiSendObj(out, req, http.StatusBadRequest, nil)
+			} else {
+				networks := node.Networks()
+				for _, nw := range networks {
+					if nw.id == queriedID {
+						_ = node.Leave(queriedID)
+						_ = apiSendObj(out, req, http.StatusOK, nw)
+						return
+					}
+				}
+				_ = apiSendObj(out, req, http.StatusNotFound, nil)
+			}
+		} else if req.Method == http.MethodPost || req.Method == http.MethodPut {
 			if queriedID == 0 {
 			if queriedID == 0 {
 				_ = apiSendObj(out, req, http.StatusBadRequest, nil)
 				_ = apiSendObj(out, req, http.StatusBadRequest, nil)
 			} else {
 			} else {
@@ -377,7 +394,7 @@ func createAPIServer(basePath string, node *Node) (*http.Server, error) {
 				_ = apiSendObj(out, req, http.StatusNotFound, nil)
 				_ = apiSendObj(out, req, http.StatusNotFound, nil)
 			}
 			}
 		} else {
 		} else {
-			out.Header().Set("Allow", "GET, HEAD, PUT, POST")
+			out.Header().Set("Allow", "GET, HEAD, PUT, POST, DELETE")
 			_ = apiSendObj(out, req, http.StatusMethodNotAllowed, nil)
 			_ = apiSendObj(out, req, http.StatusMethodNotAllowed, nil)
 		}
 		}
 	})
 	})
@@ -401,11 +418,24 @@ func createAPIServer(basePath string, node *Node) (*http.Server, error) {
 			queriedName = req.URL.Path[6:]
 			queriedName = req.URL.Path[6:]
 		}
 		}
 
 
-		if req.Method == http.MethodPost || req.Method == http.MethodPut {
+		if req.Method == http.MethodDelete {
+			if len(queriedName) > 0 {
+				roots := node.Roots()
+				for _, r := range roots {
+					if r.Name == queriedName {
+						node.RemoveRoot(queriedName)
+						_ = apiSendObj(out, req, http.StatusOK, r)
+						return
+					}
+				}
+			}
+			_ = apiSendObj(out, req, http.StatusNotFound, nil)
+		} else if req.Method == http.MethodPost || req.Method == http.MethodPut {
 			var r Root
 			var r Root
 			if apiReadObj(out, req, &r) == nil {
 			if apiReadObj(out, req, &r) == nil {
-				if r.Name != queriedName && (r.Locator == nil || r.Locator.Identity == nil || r.Locator.Identity.address.String() != queriedName) {
+				if r.Name != queriedName {
 					_ = apiSendObj(out, req, http.StatusBadRequest, nil)
 					_ = apiSendObj(out, req, http.StatusBadRequest, nil)
+					return
 				}
 				}
 				err := node.SetRoot(r.Name, r.Locator)
 				err := node.SetRoot(r.Name, r.Locator)
 				if err != nil {
 				if err != nil {
@@ -431,7 +461,7 @@ func createAPIServer(basePath string, node *Node) (*http.Server, error) {
 			}
 			}
 			_ = apiSendObj(out, req, http.StatusNotFound, nil)
 			_ = apiSendObj(out, req, http.StatusNotFound, nil)
 		} else {
 		} else {
-			out.Header().Set("Allow", "GET, HEAD, PUT, POST")
+			out.Header().Set("Allow", "GET, HEAD, PUT, POST, DELETE")
 			_ = apiSendObj(out, req, http.StatusMethodNotAllowed, nil)
 			_ = apiSendObj(out, req, http.StatusMethodNotAllowed, nil)
 		}
 		}
 	})
 	})