* Module name changed to `github.com/rajch/weave` * Added environment variable `CHECKPOINT_DISABLE=1` to default manifests, to bypass weaveworks telemetry
105 lines
3.1 KiB
Go
105 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/gorilla/mux"
|
|
|
|
"github.com/rajch/weave/ipam"
|
|
)
|
|
|
|
// 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"`
|
|
PeerCount int `json:"peercount"`
|
|
}
|
|
|
|
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: (%v) %v", err, response)
|
|
return err
|
|
}
|
|
|
|
func peerDiscoveryUpdate(discoveryEndpoint, token, peername, nickname string, addresses []string) ([]string, int, error) {
|
|
request := PeerUpdateRequest{
|
|
Name: peername,
|
|
Nickname: nickname,
|
|
Addresses: addresses,
|
|
}
|
|
var updateResponse PeerUpdateResponse
|
|
err := do("POST", discoveryEndpoint, token, request, &updateResponse)
|
|
return updateResponse.Addresses, updateResponse.PeerCount, err
|
|
}
|
|
|
|
func peerDiscoveryDelete(discoveryEndpoint, token, peername string) error {
|
|
request := PeerUpdateRequest{Name: peername}
|
|
return do("DELETE", discoveryEndpoint, token, request, nil)
|
|
}
|
|
|
|
func HandleHTTPPeer(router *mux.Router, alloc *ipam.Allocator, discoveryEndpoint, token, peername string) {
|
|
router.Methods("DELETE").Path("/peer").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if discoveryEndpoint != "" && token != "" {
|
|
if err := peerDiscoveryDelete(discoveryEndpoint, token, peername); err != nil {
|
|
Log.Errorf("Error while deleting self from peer discovery: %s", err)
|
|
}
|
|
}
|
|
if alloc != nil {
|
|
alloc.Shutdown()
|
|
}
|
|
w.WriteHeader(204)
|
|
})
|
|
|
|
router.Methods("DELETE").Path("/peer/{id}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
ident := mux.Vars(r)["id"]
|
|
if discoveryEndpoint != "" && token != "" {
|
|
// TODO: deal with this being either a peername or a nickname
|
|
if err := peerDiscoveryDelete(discoveryEndpoint, token, ident); err != nil {
|
|
Log.Errorf("Error while deleting self from peer discovery: %s", err)
|
|
}
|
|
}
|
|
if alloc != nil {
|
|
transferred := alloc.AdminTakeoverRanges(ident)
|
|
fmt.Fprintf(w, "%d IPs taken over from %s\n", transferred, ident)
|
|
}
|
|
})
|
|
}
|