blob: 01d56349b70b43a9851d1589148e4616d0d6a93c [file] [log] [blame]
Sergiusz Bazanskie08e6da2018-08-27 20:40:10 +01001package main
2
3import (
4 "context"
Sergiusz Bazanskie08e6da2018-08-27 20:40:10 +01005 "fmt"
Sergiusz Bazanskie08e6da2018-08-27 20:40:10 +01006 "net"
7 "net/http"
8
Sergiusz Bazanskif9d85cf2018-08-28 14:13:36 +01009 "code.hackerspace.pl/q3k/hspki"
Sergiusz Bazanskie08e6da2018-08-27 20:40:10 +010010 "github.com/golang/glog"
11 "github.com/q3k/statusz"
12 "golang.org/x/net/trace"
13 "google.golang.org/grpc"
Sergiusz Bazanskie08e6da2018-08-27 20:40:10 +010014 "google.golang.org/grpc/reflection"
15
16 pb "code.hackerspace.pl/q3k/arista-proxy/proto"
17)
18
19type serverOpts struct {
20 listenAddress string
21 debugAddress string
22 tlsCAPath string
23 tlsCertificatePath string
24 tlsKeyPath string
Sergiusz Bazanskie08e6da2018-08-27 20:40:10 +010025}
26
27type server struct {
28 arista *aristaClient
29 opts *serverOpts
30
31 grpc struct {
32 listen net.Listener
33 server *grpc.Server
34 }
35 http struct {
36 listen net.Listener
37 server *http.Server
38 }
39}
40
41func newServer(opts *serverOpts, arista *aristaClient) (*server, error) {
42 return &server{
43 opts: opts,
44 arista: arista,
45 }, nil
46}
47
48func (s *server) trace(ctx context.Context, f string, args ...interface{}) {
49 tr, ok := trace.FromContext(ctx)
50 if !ok {
51 fmtd := fmt.Sprintf(f, args...)
52 glog.Warningf("No trace in %v: %s", ctx, fmtd)
53 return
54 }
55 tr.LazyPrintf(f, args...)
56}
57
58func (s *server) setupGRPC(options ...grpc.ServerOption) error {
Sergiusz Bazanskie08e6da2018-08-27 20:40:10 +010059 lis, err := net.Listen("tcp", s.opts.listenAddress)
60 if err != nil {
61 return fmt.Errorf("while listening on main port: %v", err)
62 }
63
Sergiusz Bazanskie08e6da2018-08-27 20:40:10 +010064 s.grpc.listen = lis
Sergiusz Bazanskie08e6da2018-08-27 20:40:10 +010065 s.grpc.server = grpc.NewServer(options...)
66
67 return nil
68}
69
70func (s *server) setupDebugHTTP(mux http.Handler) error {
71 lis, err := net.Listen("tcp", s.opts.debugAddress)
72 if err != nil {
73 return fmt.Errorf("while listening on main port: %v", err)
74 }
75
76 s.http.listen = lis
77 s.http.server = &http.Server{
78 Addr: s.opts.debugAddress,
79 Handler: mux,
80 }
81
82 return nil
83}
84
85func (s *server) serveForever() {
86 grpc.EnableTracing = true
87
Sergiusz Bazanski5cb204b2018-08-28 15:08:00 +010088 if err := s.setupGRPC(hspki.WithServerHSPKI()...); err != nil {
Sergiusz Bazanskie08e6da2018-08-27 20:40:10 +010089 glog.Exitf("Could not setup GRPC server: %v", err)
90 }
91 pb.RegisterAristaProxyServer(s.grpc.server, s)
92 reflection.Register(s.grpc.server)
93
94 go func() {
95 if err := s.grpc.server.Serve(s.grpc.listen); err != nil {
96 glog.Exitf("Could not start GRPC server: %v", err)
97 }
98 }()
99 glog.Infof("Listening for GRPC on %v", s.opts.listenAddress)
100
Sergiusz Bazanskib27d5282018-08-27 21:07:23 +0100101 if s.opts.debugAddress == "" {
102 glog.Info("Disabling debug HTTP server")
103 } else {
104 httpMux := http.NewServeMux()
105 httpMux.HandleFunc("/debug/status", statusz.StatusHandler)
106 httpMux.HandleFunc("/debug/requests", trace.Traces)
107 httpMux.HandleFunc("/", statusz.StatusHandler)
Sergiusz Bazanskie08e6da2018-08-27 20:40:10 +0100108
Sergiusz Bazanskib27d5282018-08-27 21:07:23 +0100109 if err := s.setupDebugHTTP(httpMux); err != nil {
110 glog.Exitf("Could not setup HTTP server: %v", err)
Sergiusz Bazanskie08e6da2018-08-27 20:40:10 +0100111 }
Sergiusz Bazanskib27d5282018-08-27 21:07:23 +0100112
113 go func() {
114 if err := s.http.server.Serve(s.http.listen); err != nil {
115 glog.Exitf("Could not start HTTP server: %v", err)
116 }
117 }()
118 glog.Infof("Listening for HTTP on %v", s.opts.debugAddress)
119 }
Sergiusz Bazanskie08e6da2018-08-27 20:40:10 +0100120
121 select {}
122}