package main import ( "context" "fmt" "net" "net/http" "code.hackerspace.pl/q3k/hspki" "github.com/golang/glog" "github.com/q3k/statusz" "golang.org/x/net/trace" "google.golang.org/grpc" "google.golang.org/grpc/reflection" pb "code.hackerspace.pl/q3k/arista-proxy/proto" ) type serverOpts struct { listenAddress string debugAddress string tlsCAPath string tlsCertificatePath string tlsKeyPath string } type server struct { arista *aristaClient opts *serverOpts grpc struct { listen net.Listener server *grpc.Server } http struct { listen net.Listener server *http.Server } } func newServer(opts *serverOpts, arista *aristaClient) (*server, error) { return &server{ opts: opts, arista: arista, }, nil } func (s *server) trace(ctx context.Context, f string, args ...interface{}) { tr, ok := trace.FromContext(ctx) if !ok { fmtd := fmt.Sprintf(f, args...) glog.Warningf("No trace in %v: %s", ctx, fmtd) return } tr.LazyPrintf(f, args...) } func (s *server) setupGRPC(options ...grpc.ServerOption) error { lis, err := net.Listen("tcp", s.opts.listenAddress) if err != nil { return fmt.Errorf("while listening on main port: %v", err) } s.grpc.listen = lis s.grpc.server = grpc.NewServer(options...) return nil } func (s *server) setupDebugHTTP(mux http.Handler) error { lis, err := net.Listen("tcp", s.opts.debugAddress) if err != nil { return fmt.Errorf("while listening on main port: %v", err) } s.http.listen = lis s.http.server = &http.Server{ Addr: s.opts.debugAddress, Handler: mux, } return nil } func (s *server) serveForever() { grpc.EnableTracing = true if err := s.setupGRPC(hspki.WithServerHSPKI()...); err != nil { glog.Exitf("Could not setup GRPC server: %v", err) } pb.RegisterAristaProxyServer(s.grpc.server, s) reflection.Register(s.grpc.server) go func() { if err := s.grpc.server.Serve(s.grpc.listen); err != nil { glog.Exitf("Could not start GRPC server: %v", err) } }() glog.Infof("Listening for GRPC on %v", s.opts.listenAddress) if s.opts.debugAddress == "" { glog.Info("Disabling debug HTTP server") } else { httpMux := http.NewServeMux() httpMux.HandleFunc("/debug/status", statusz.StatusHandler) httpMux.HandleFunc("/debug/requests", trace.Traces) httpMux.HandleFunc("/", statusz.StatusHandler) if err := s.setupDebugHTTP(httpMux); err != nil { glog.Exitf("Could not setup HTTP server: %v", err) } go func() { if err := s.http.server.Serve(s.http.listen); err != nil { glog.Exitf("Could not start HTTP server: %v", err) } }() glog.Infof("Listening for HTTP on %v", s.opts.debugAddress) } select {} }