This commit is contained in:
Adam Ierymenko 2019-10-01 13:09:53 -07:00
parent 1711cced3e
commit d1b780c7be
No known key found for this signature in database
GPG Key ID: C8877CF2D7A5D7F3
4 changed files with 99 additions and 9 deletions
go
cmd/zerotier/cli
pkg/zerotier

View File

@ -13,6 +13,49 @@
package cli
import (
"fmt"
"io/ioutil"
"net/url"
"os"
"strings"
"zerotier/pkg/zerotier"
)
// AddRoot CLI command
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)
}

View File

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

View File

@ -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 {
if f {
return "ENABLED"

View File

@ -74,8 +74,11 @@ func APIPost(basePath, socketName, authToken, queryPath string, post, result int
if err != nil {
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
@ -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 {
_ = apiSendObj(out, req, http.StatusBadRequest, nil)
} else {
@ -377,7 +394,7 @@ func createAPIServer(basePath string, node *Node) (*http.Server, error) {
_ = apiSendObj(out, req, http.StatusNotFound, nil)
}
} else {
out.Header().Set("Allow", "GET, HEAD, PUT, POST")
out.Header().Set("Allow", "GET, HEAD, PUT, POST, DELETE")
_ = apiSendObj(out, req, http.StatusMethodNotAllowed, nil)
}
})
@ -401,11 +418,24 @@ func createAPIServer(basePath string, node *Node) (*http.Server, error) {
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
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)
return
}
err := node.SetRoot(r.Name, r.Locator)
if err != nil {
@ -431,7 +461,7 @@ func createAPIServer(basePath string, node *Node) (*http.Server, error) {
}
_ = apiSendObj(out, req, http.StatusNotFound, nil)
} else {
out.Header().Set("Allow", "GET, HEAD, PUT, POST")
out.Header().Set("Allow", "GET, HEAD, PUT, POST, DELETE")
_ = apiSendObj(out, req, http.StatusMethodNotAllowed, nil)
}
})