| 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 {} |
| } |