blob: 90061fb36066da090c1ab66a75025f7b1e7f6b7a [file] [log] [blame]
package main
import (
"context"
"flag"
"strconv"
"strings"
"github.com/golang/glog"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"code.hackerspace.pl/hscloud/bgpwtf/cccampix/irr/provider"
pb "code.hackerspace.pl/hscloud/bgpwtf/cccampix/proto"
"code.hackerspace.pl/hscloud/go/mirko"
)
type service struct {
iana *provider.IANA
providers map[provider.IRR]provider.Provider
}
func main() {
flag.Parse()
mi := mirko.New()
if err := mi.Listen(); err != nil {
glog.Exitf("Listen failed: %v", err)
}
s := &service{
iana: provider.NewIANA(2),
providers: map[provider.IRR]provider.Provider{
provider.IRR_RIPE: provider.NewRIPE(10),
provider.IRR_ARIN: provider.NewARIN(2),
},
}
pb.RegisterIRRServer(mi.GRPC(), s)
if err := mi.Serve(); err != nil {
glog.Exitf("Serve failed: %v", err)
}
<-mi.Done()
}
// Query returns parsed RPSL data for a given aut-num objects in any of the
// supported IRRs.
func (s *service) Query(ctx context.Context, req *pb.IRRQueryRequest) (*pb.IRRQueryResponse, error) {
if req.As == "" {
return nil, status.Error(codes.InvalidArgument, "as must be given")
}
req.As = strings.ToLower(req.As)
if strings.HasPrefix(req.As, "as") {
req.As = req.As[2:]
}
asn, err := strconv.ParseUint(req.As, 10, 64)
if err != nil {
return nil, status.Error(codes.InvalidArgument, "as is invalid")
}
irr, err := s.iana.Who(ctx, asn)
if err != nil {
return nil, status.Errorf(codes.Unavailable, "could not find AS block delegation from IANA: %v", err)
}
prov, ok := s.providers[irr]
if !ok {
return nil, status.Errorf(codes.Unimplemented, "AS belongs to unhandled IRR %s", irr.String())
}
res, err := prov.Query(ctx, asn)
return res, err
}