Peer Discovery via a web service
This commit is contained in:
1 parent
09977a2e04
commit
e2d644b86b
3 files changed
+110
-2
No files matched your search
@@ -82,3 +82,25 @@ func findInterface(ifaceName string) (iface *net.Interface, err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func LocalAddresses() ([]*net.IPNet, error) {
|
||||
links, err := netlink.LinkList()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
retval := []*net.IPNet{}
|
||||
for _, link := range links {
|
||||
if _, isBridge := link.(*netlink.Bridge); isBridge || (link.Attrs().Flags&net.FlagLoopback) != 0 {
|
||||
continue
|
||||
}
|
||||
addrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
retval = append(retval, addr.IPNet)
|
||||
}
|
||||
}
|
||||
return retval, nil
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TODO: move these definitions somewhere more shareable
|
||||
type PeerUpdateRequest struct {
|
||||
Name string `json:"peername"`
|
||||
Nickname string `json:"nickname"` // optional
|
||||
Addresses []string `json:"addresses"` // can be empty
|
||||
}
|
||||
|
||||
type PeerUpdateResponse struct {
|
||||
Addresses []string `json:"addresses"`
|
||||
}
|
||||
|
||||
var httpClient = &http.Client{Timeout: 30 * time.Second}
|
||||
|
||||
func do(verb string, discoveryEndpoint, token string, request interface{}, response interface{}) error {
|
||||
body := new(bytes.Buffer)
|
||||
err := json.NewEncoder(body).Encode(request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req, err := http.NewRequest(verb, discoveryEndpoint+"/peer", body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Scope-Probe token=%s", token))
|
||||
req.Header.Set("X-Weave-Net-Version", version)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
Log.Printf("Calling peer discovery %s with %s", req.URL, request)
|
||||
resp, err := httpClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
rbody, _ := ioutil.ReadAll(resp.Body)
|
||||
return errors.New(resp.Status + ": " + string(rbody))
|
||||
}
|
||||
if response == nil {
|
||||
return nil
|
||||
}
|
||||
err = json.NewDecoder(resp.Body).Decode(response)
|
||||
Log.Printf("peer discovery result: (%s) %v", err, response)
|
||||
return err
|
||||
}
|
||||
|
||||
func peerDiscoveryUpdate(discoveryEndpoint, token, peername, nickname string, addresses []string) ([]string, error) {
|
||||
request := PeerUpdateRequest{
|
||||
Name: peername,
|
||||
Nickname: nickname,
|
||||
Addresses: addresses,
|
||||
}
|
||||
var updateResponse PeerUpdateResponse
|
||||
err := do("POST", discoveryEndpoint, token, request, &updateResponse)
|
||||
return updateResponse.Addresses, err
|
||||
}
|
||||
+22
-2
@@ -143,6 +143,9 @@ func main() {
|
||||
trustedSubnetStr string
|
||||
dbPrefix string
|
||||
isAWSVPC bool
|
||||
discoveryEndpoint string
|
||||
token string
|
||||
advertiseAddress string
|
||||
|
||||
defaultDockerHost = "unix:///var/run/docker.sock"
|
||||
)
|
||||
@@ -184,6 +187,9 @@ func main() {
|
||||
mflag.StringVar(&trustedSubnetStr, []string{"-trusted-subnets"}, "", "comma-separated list of trusted subnets in CIDR notation")
|
||||
mflag.StringVar(&dbPrefix, []string{"-db-prefix"}, "/weavedb/weave", "pathname/prefix of filename to store data")
|
||||
mflag.BoolVar(&isAWSVPC, []string{"-awsvpc"}, false, "use AWS VPC for routing")
|
||||
mflag.StringVar(&discoveryEndpoint, []string{"-peer-discovery-url"}, "https://cloud.weave.works/api/weavenet", "url for peer discovery")
|
||||
mflag.StringVar(&token, []string{"-token"}, "", "token for peer discovery")
|
||||
mflag.StringVar(&advertiseAddress, []string{"-advertise-address"}, "", "address to advertise for peer discovery")
|
||||
|
||||
// crude way of detecting that we probably have been started in a
|
||||
// container, with `weave launch` --> suppress misleading paths in
|
||||
@@ -257,7 +263,21 @@ func main() {
|
||||
router := weave.NewNetworkRouter(config, networkConfig, name, nickName, overlay, db)
|
||||
Log.Println("Our name is", router.Ourself)
|
||||
|
||||
if peers, err = router.InitialPeers(resume, peers); err != nil {
|
||||
if token != "" {
|
||||
var addresses []string
|
||||
if advertiseAddress == "" {
|
||||
localAddrs, err := weavenet.LocalAddresses()
|
||||
checkFatal(err)
|
||||
for _, addr := range localAddrs {
|
||||
addresses = append(addresses, addr.IP.String())
|
||||
}
|
||||
} else {
|
||||
addresses = strings.Split(advertiseAddress, ",")
|
||||
}
|
||||
discoveredPeers, err := peerDiscoveryUpdate(discoveryEndpoint, token, name.String(), nickName, addresses)
|
||||
checkFatal(err) // TODO: what if it is a transient error, and we are restarting?
|
||||
peers = append(peers, discoveredPeers...)
|
||||
} else if peers, err = router.InitialPeers(resume, peers); err != nil {
|
||||
Log.Fatal("Unable to get initial peer set: ", err)
|
||||
}
|
||||
|
||||
@@ -376,7 +396,7 @@ func options() map[string]string {
|
||||
mflag.Visit(func(f *mflag.Flag) {
|
||||
value := f.Value.String()
|
||||
name := canonicalName(f)
|
||||
if name == "password" {
|
||||
if name == "password" || name == "token" {
|
||||
value = "<redacted>"
|
||||
}
|
||||
options[name] = value
|
||||
|
||||
Reference in new issue
Block a user