Skip to content

Commit

Permalink
Implement first iteration of Redis Caching
Browse files Browse the repository at this point in the history
  • Loading branch information
f0o committed Sep 1, 2024
1 parent f91d0d2 commit ce34696
Show file tree
Hide file tree
Showing 15 changed files with 238 additions and 108 deletions.
5 changes: 5 additions & 0 deletions example.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ grpc: # gRPC
cert: "/path/to/cert" # certificate path (becomes optional if self_signed is true)
key: "/path/to/key" # private key path (becomes optional if self_signed is true)

redis: # Redis Cache Settings
enabled: true # Enable or disable cache
ttl: 5m # Cache TTL in seconds
uri: "redis://redis-svc:6379/0?protocol=3" # Redis host URI

web: # WebUI Settings, Most if not all of these are entirely optional
enabled: true # Enable or disable web interface
grpc_url: "" # URI of the GRCP server; uses current host as viewed by the browser if not set (optional)
Expand Down
13 changes: 8 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ go 1.22
require (
connectrpc.com/connect v1.16.2
connectrpc.com/grpchealth v1.3.0
github.com/rs/cors v1.11.0
golang.org/x/crypto v0.25.0
golang.org/x/net v0.27.0
github.com/redis/go-redis/v9 v9.6.1
github.com/rs/cors v1.11.1
golang.org/x/crypto v0.26.0
golang.org/x/net v0.28.0
google.golang.org/protobuf v1.34.2
gopkg.in/yaml.v2 v2.4.0
)

require (
golang.org/x/sys v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
golang.org/x/sys v0.24.0 // indirect
golang.org/x/text v0.17.0 // indirect
)
34 changes: 22 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,30 @@ connectrpc.com/connect v1.16.2 h1:ybd6y+ls7GOlb7Bh5C8+ghA6SvCBajHwxssO2CGFjqE=
connectrpc.com/connect v1.16.2/go.mod h1:n2kgwskMHXC+lVqb18wngEpF95ldBHXjZYJussz5FRc=
connectrpc.com/grpchealth v1.3.0 h1:FA3OIwAvuMokQIXQrY5LbIy8IenftksTP/lG4PbYN+E=
connectrpc.com/grpchealth v1.3.0/go.mod h1:3vpqmX25/ir0gVgW6RdnCPPZRcR6HvqtXX5RNPmDXHM=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po=
github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4=
github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA=
github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
Expand Down
26 changes: 25 additions & 1 deletion protobuf/lookingglass/v0/lookingglass.proto
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,16 @@ message GetRoutersResponse {

// The next page token.
uint32 next_page = 2;

// Age of Response
google.protobuf.Timestamp timestamp = 3;
}

// PingRequest is the request message for Ping.
message PingRequest {
// The ID of the router.
int64 router_id = 1;

// The IP address to ping.
string target = 2;
}
Expand All @@ -88,12 +92,16 @@ message PingRequest {
message PingResponse {
// The result of the ping.
string result = 1;

// Age of Response
google.protobuf.Timestamp timestamp = 2;
}

// TracerouteRequest is the request message for Traceroute.
message TracerouteRequest {
// The ID of the router.
int64 router_id = 1;

// The IP address to traceroute.
string target = 2;
}
Expand All @@ -102,6 +110,9 @@ message TracerouteRequest {
message TracerouteResponse {
// The result of the traceroute.
string result = 1;

// Age of Response
google.protobuf.Timestamp timestamp = 2;
}

// BGPSummaryRequest is the request message for BGPSummary.
Expand All @@ -114,12 +125,16 @@ message BGPSummaryRequest {
message BGPSummaryResponse {
// The BGP summary.
string result = 1;

// Age of Response
google.protobuf.Timestamp timestamp = 2;
}

// BGPRouteRequest is the request message for BGPRoute.
message BGPRouteRequest {
// The ID of the router.
int64 router_id = 1;

// The IP address to look up.
string target = 2;
}
Expand All @@ -128,6 +143,9 @@ message BGPRouteRequest {
message BGPRouteResponse {
// The BGP route.
string result = 1;

// Age of Response
google.protobuf.Timestamp timestamp = 2;
}

// BGPCommunityRequest is the request message for BGPCommunity.
Expand All @@ -142,12 +160,16 @@ message BGPCommunityRequest {
message BGPCommunityResponse {
// The BGP community.
string result = 1;

// Age of Response
google.protobuf.Timestamp timestamp = 2;
}

// BGPASPathRequest is the request message for BGPASPath.
message BGPASPathRequest {
// The ID of the router.
int64 router_id = 1;

// The IP address to look up.
string pattern = 2;
}
Expand All @@ -156,5 +178,7 @@ message BGPASPathRequest {
message BGPASPathResponse {
// The BGP AS path.
string result = 1;
}

// Age of Response
google.protobuf.Timestamp timestamp = 2;
}
9 changes: 5 additions & 4 deletions protobuf/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 3 additions & 43 deletions server/http/grpc/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,56 +5,16 @@ import (
"log"
"net/http"
"time"
"unsafe"

"connectrpc.com/connect"
"connectrpc.com/grpchealth"
"github.com/AS203038/looking-glass/protobuf/lookingglass/v0/lookingglassconnect"
"github.com/AS203038/looking-glass/server/utils"
)

var Health = grpchealth.NewStaticChecker(lookingglassconnect.LookingGlassServiceName)

func NewLogInterceptor() connect.UnaryInterceptorFunc {
interceptor := func(next connect.UnaryFunc) connect.UnaryFunc {
return connect.UnaryFunc(func(
ctx context.Context,
req connect.AnyRequest,
) (connect.AnyResponse, error) {
start := time.Now()

// Call the original handler
r, e := next(ctx, req)

// Log the request
n := 200
if e != nil {
n = 500
}
p := req.Header().Get("X-Forwarded-For")
if p == "" {
p = req.Peer().Addr
}
log.Printf("%s \"%s %s %s\" %d %d \"%s\" \"%s\" %s",
p,
req.HTTPMethod(),
req.Spec().Procedure,
req.Peer().Protocol,
n,
unsafe.Sizeof(req.Any()),
req.Header().Get("Referer"),
req.Header().Get("User-Agent"),
time.Since(start),
)
return r, e
})
}
return connect.UnaryInterceptorFunc(interceptor)
}

func Mux(ctx context.Context, mux *http.ServeMux, rts utils.RouterMap) {
interceptors := connect.WithInterceptors(NewLogInterceptor())
mux.Handle(lookingglassconnect.NewLookingGlassServiceHandler(NewLookingGlassService(ctx, rts), interceptors))
mux.Handle(lookingglassconnect.NewLookingGlassServiceHandler(NewLookingGlassService(ctx, rts)))
mux.Handle(grpchealth.NewHandler(Health))
Health.SetStatus(lookingglassconnect.LookingGlassServiceName, grpchealth.StatusServing)
go healthcheck(ctx, rts)
Expand All @@ -72,12 +32,12 @@ func healthcheck(ctx context.Context, rts utils.RouterMap) {
if err := r.Healthcheck(); err == nil {
if !o {
Health.SetStatus(lookingglassconnect.LookingGlassServiceName+"/"+r.Config.Name, grpchealth.StatusServing)
log.Printf("Router %s is healthy", r.Config.Name)
log.Printf("NOTICE: Router %s is healthy", r.Config.Name)
}
} else {
if o {
Health.SetStatus(lookingglassconnect.LookingGlassServiceName+"/"+r.Config.Name, grpchealth.StatusNotServing)
log.Printf("Router %s is unhealthy: %s", r.Config.Name, err)
log.Printf("WARNING: Router %s is unhealthy: %s", r.Config.Name, err)
}
}
}
Expand Down
26 changes: 26 additions & 0 deletions server/http/grpc/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os"
"strconv"
"strings"
"time"

"connectrpc.com/connect"
pb "github.com/AS203038/looking-glass/protobuf/lookingglass/v0"
Expand Down Expand Up @@ -97,8 +98,13 @@ func (s *LookingGlassService) Ping(ctx context.Context, req *connect.Request[pb.
if err != nil {
return nil, err
}
ts := time.Now()
return connect.NewResponse(&pb.PingResponse{
Result: strings.Join(ret, "\n"),
Timestamp: &timestamppb.Timestamp{
Seconds: ts.Unix(),
Nanos: int32(ts.Nanosecond()),
},
}), nil
}

Expand All @@ -116,8 +122,13 @@ func (s *LookingGlassService) Traceroute(ctx context.Context, req *connect.Reque
if err != nil {
return nil, err
}
ts := time.Now()
return connect.NewResponse(&pb.TracerouteResponse{
Result: strings.Join(ret, "\n"),
Timestamp: &timestamppb.Timestamp{
Seconds: ts.Unix(),
Nanos: int32(ts.Nanosecond()),
},
}), nil
}

Expand All @@ -135,8 +146,13 @@ func (s *LookingGlassService) BGPRoute(ctx context.Context, req *connect.Request
if err != nil {
return nil, err
}
ts := time.Now()
return connect.NewResponse(&pb.BGPRouteResponse{
Result: strings.Join(ret, "\n"),
Timestamp: &timestamppb.Timestamp{
Seconds: ts.Unix(),
Nanos: int32(ts.Nanosecond()),
},
}), nil
}

Expand All @@ -151,8 +167,13 @@ func (s *LookingGlassService) BGPCommunity(ctx context.Context, req *connect.Req
if err != nil {
return nil, err
}
ts := time.Now()
return connect.NewResponse(&pb.BGPCommunityResponse{
Result: strings.Join(ret, "\n"),
Timestamp: &timestamppb.Timestamp{
Seconds: ts.Unix(),
Nanos: int32(ts.Nanosecond()),
},
}), nil
}

Expand All @@ -170,7 +191,12 @@ func (s *LookingGlassService) BGPASPath(ctx context.Context, req *connect.Reques
if err != nil {
return nil, err
}
ts := time.Now()
return connect.NewResponse(&pb.BGPASPathResponse{
Result: strings.Join(ret, "\n"),
Timestamp: &timestamppb.Timestamp{
Seconds: ts.Unix(),
Nanos: int32(ts.Nanosecond()),
},
}), nil
}
Loading

0 comments on commit ce34696

Please sign in to comment.