| package main |
| |
| import ( |
| "context" |
| "flag" |
| "net" |
| "net/http" |
| |
| "code.hackerspace.pl/q3k/hspki" |
| "github.com/golang/glog" |
| "github.com/q3k/statusz" |
| "github.com/ziutek/telnet" |
| "golang.org/x/net/trace" |
| "google.golang.org/grpc" |
| "google.golang.org/grpc/codes" |
| "google.golang.org/grpc/reflection" |
| "google.golang.org/grpc/status" |
| |
| pb "code.hackerspace.pl/q3k/m6220-proxy/proto" |
| ) |
| |
| var ( |
| flagListenAddress string |
| flagDebugAddress string |
| flagSwitchAddress string |
| flagSwitchUsername string |
| flagSwitchPassword string |
| ) |
| |
| func init() { |
| flag.Set("logtostderr", "true") |
| } |
| |
| type service struct { |
| connectionSemaphore chan int |
| } |
| |
| func (s *service) connect() (*cliClient, error) { |
| s.connectionSemaphore <- 1 |
| conn, err := telnet.Dial("tcp", flagSwitchAddress) |
| if err != nil { |
| <-s.connectionSemaphore |
| return nil, err |
| } |
| |
| cli := newCliClient(conn, flagSwitchUsername, flagSwitchPassword) |
| return cli, nil |
| } |
| |
| func (s *service) disconnect() { |
| <-s.connectionSemaphore |
| } |
| |
| func (s *service) RunCommand(ctx context.Context, req *pb.RunCommandRequest) (*pb.RunCommandResponse, error) { |
| if req.Command == "" { |
| return nil, status.Error(codes.InvalidArgument, "command cannot be null") |
| } |
| |
| cli, err := s.connect() |
| if err != nil { |
| return nil, status.Error(codes.Unavailable, "could not connect to backend") |
| } |
| defer s.disconnect() |
| |
| lines, effective, err := cli.runCommand(ctx, req.Command) |
| if err != nil { |
| return nil, err |
| } |
| res := &pb.RunCommandResponse{ |
| EffectiveCommand: effective, |
| Lines: lines, |
| } |
| return res, nil |
| } |
| |
| func main() { |
| flag.StringVar(&flagListenAddress, "listen_address", "127.0.0.1:42000", "Address to listen on for gRPC") |
| flag.StringVar(&flagDebugAddress, "debug_address", "127.0.0.1:42001", "Address to listen on for Debug HTTP") |
| flag.StringVar(&flagSwitchAddress, "switch_address", "127.0.0.1:23", "Telnet address of M6220") |
| flag.StringVar(&flagSwitchUsername, "switch_username", "admin", "Switch login username") |
| flag.StringVar(&flagSwitchPassword, "switch_password", "admin", "Switch login password") |
| flag.Parse() |
| |
| s := &service{ |
| connectionSemaphore: make(chan int, 1), |
| } |
| |
| grpc.EnableTracing = true |
| grpcLis, err := net.Listen("tcp", flagListenAddress) |
| if err != nil { |
| glog.Exitf("Could not listen on %v: %v", flagListenAddress, err) |
| } |
| grpcSrv := grpc.NewServer(hspki.WithServerHSPKI()...) |
| pb.RegisterM6220ProxyServer(grpcSrv, s) |
| reflection.Register(grpcSrv) |
| |
| glog.Infof("Starting gRPC on %v", flagListenAddress) |
| go func() { |
| if err := grpcSrv.Serve(grpcLis); err != nil { |
| glog.Exitf("Could not start gRPC: %v", err) |
| } |
| }() |
| |
| if flagDebugAddress != "" { |
| glog.Infof("Starting debug on %v", flagDebugAddress) |
| httpMux := http.NewServeMux() |
| httpMux.HandleFunc("/debug/status", statusz.StatusHandler) |
| httpMux.HandleFunc("/debug/requests", trace.Traces) |
| httpMux.HandleFunc("/", statusz.StatusHandler) |
| |
| httpLis, err := net.Listen("tcp", flagDebugAddress) |
| if err != nil { |
| glog.Exitf("Could not listen on %v: %v", flagDebugAddress, err) |
| } |
| httpSrv := &http.Server{ |
| Addr: flagDebugAddress, |
| Handler: httpMux, |
| } |
| |
| go func() { |
| if err := httpSrv.Serve(httpLis); err != nil { |
| glog.Exitf("Could not start HTTP server: %v", err) |
| } |
| }() |
| |
| } |
| |
| glog.Infof("Running!") |
| |
| select {} |
| } |