Skip to content

Commit

Permalink
Fixed routing check
Browse files Browse the repository at this point in the history
  • Loading branch information
lawrencegripper committed Dec 4, 2017
1 parent b640e7c commit 3850f90
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 10 deletions.
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ func publishToAppInsights(event types.StatsEvent, config types.Configuration) {
client := appinsights.NewTelemetryClient(config.AppInsightsKey)
telemetry := appinsights.NewEventTelemetry(config.InstanceID)
telemetry.SetProperty("sourceTime", event.SourceTime.String())
telemetry.SetProperty("source", event.Source)
telemetry.SetProperty("instanceID", config.InstanceID) //Duplicated for discoverability
telemetry.SetProperty("isSuccess", strconv.FormatBool(event.IsSuccess))
telemetry.SetProperty("requestDuration", event.RequestDuration.String())
if !event.IsSuccess {
Expand Down
28 changes: 19 additions & 9 deletions routing/routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"net/http"
"time"

"github.com/cloudflare/cfssl/log"
"github.com/google/uuid"
"github.com/lawrencegripper/traefik-appinsights-watchdog/types"
)
Expand All @@ -21,27 +20,29 @@ func StartCheck(config types.Configuration, healthChannel chan<- types.StatsEven
FabricURI: config.TraefikBackendName,
TraefikServiceURL: config.WatchdogTraefikURL,
StartTime: time.Now(),
InstanceID: config.InstanceID,
Nonce: uuid.New().String(),
}
intervalDuration := time.Second * time.Duration(config.PollIntervalSec)
go context.runServer()
for {
context.StartTime = time.Now()
nonceUUID, _ := uuid.NewUUID()
context.Nonce = nonceUUID.String()
context.Nonce = uuid.New().String()
healthChannel <- context.makeRequest()
time.Sleep(intervalDuration)
}
}

func (context *RequestContext) receiveHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println(r.Cookie(generateCookieName(context.FabricURI)))
w.Header().Set("x-response-from", context.InstanceID)
w.WriteHeader(http.StatusOK)
w.Write([]byte(context.Nonce))
}

func (context *RequestContext) runServer() {
http.HandleFunc("/", context.receiveHandler)
err := http.ListenAndServe(fmt.Sprintf("localhost:%v", context.Port), nil)
err := http.ListenAndServe(fmt.Sprintf(":%v", context.Port), nil)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -71,7 +72,8 @@ func (context *RequestContext) makeRequest() types.StatsEvent {
Expires: time.Now().Add(time.Hour),
Domain: "localhost",
Name: generateCookieName(context.FabricURI),
Value: fmt.Sprintf("http://%v:%v", getOutboundIP(), context.Port),
Value: fmt.Sprintf("http://%v:%v/", getOutboundIP(), context.Port),
Path: "/",
})

result, err := client.Do(req)
Expand All @@ -87,14 +89,20 @@ func (context *RequestContext) makeRequest() types.StatsEvent {
return event
}

responseFrom := result.Header.Get("x-response-from")
if responseFrom != context.InstanceID {
event.ErrorDetails = fmt.Sprintf("Response from wrong instance expected: %s got response from: %s", context.InstanceID, responseFrom)
return event
}

body, err := ioutil.ReadAll(result.Body)
if err != nil {
event.ErrorDetails = "Unable to read request body"
return event
}

if string(body) != context.Nonce {
event.ErrorDetails = fmt.Sprintf("Returned value doesn't match expected %s", string(body))
event.ErrorDetails = fmt.Sprintf("Returned value doesn't match got: %s expected: %s response was from: %s", string(body), context.Nonce, responseFrom)
return event
}

Expand All @@ -112,17 +120,19 @@ func generateCookieName(backendName string) string {
_, err := hash.Write(data)
if err != nil {
// Impossible case
log.Errorf("Fail to create cookie name: %v", err)
panic(err)
}

return fmt.Sprintf("_%x", hash.Sum(nil))[:cookieNameLength]
}

// Get preferred outbound ip of this machine
// no connection is made so no traffic leaves the box.
// conn object only used to find ip
func getOutboundIP() net.IP {
conn, err := net.Dial("udp", "127.0.0.1:80")
conn, err := net.Dial("udp", "8.8.8.8:80")
if err != nil {
log.Fatal(err)
panic(err)
}
defer conn.Close()

Expand Down
4 changes: 3 additions & 1 deletion routing/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package routing

import "time"

// RequestContext is used to hold the nonce and other configuration information during a routing check
type RequestContext struct {
Nonce string
StartTime time.Time
Port int
TraefikServiceURL string
FabricURI string
BackendURL string
}
InstanceID string
}

0 comments on commit 3850f90

Please sign in to comment.