package main import ( "context" "flag" "github.com/golang/glog" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "code.hackerspace.pl/hscloud/bgpwtf/cccampix/peeringdb/schema" pb "code.hackerspace.pl/hscloud/bgpwtf/cccampix/proto" "code.hackerspace.pl/hscloud/go/mirko" ) type service struct { } func (s *service) GetIXMembers(ctx context.Context, req *pb.GetIXMembersRequest) (*pb.GetIXMembersResponse, error) { if req.Id == 0 { return nil, status.Error(codes.InvalidArgument, "IX id must be given") } // First, get netixlans (membership info) for the given IX. js := struct { Data []schema.NetIXLan `json:"Data"` }{} err := schema.Get(ctx, &js, schema.NetIXLanInIXURL(req.Id)) if err != nil { return nil, status.Errorf(codes.Unavailable, "PeeringDB query error: %v", err) } // Build set of seen Nets/ASs. netids := make(map[int64]bool) for _, netixlan := range js.Data { netids[netixlan.NetID] = true } // Convert set to unique list. nets := make([]int64, len(netids)) i := 0 for id, _ := range netids { nets[i] = id i += 1 } // Request information about nets/ASNs: js2 := struct { Data []schema.Net `json:"Data"` }{} err = schema.Get(ctx, &js2, schema.NetURLMulti(nets)) if err != nil { return nil, status.Errorf(codes.Unavailable, "PeeringDB query error: %v", err) } // Make map net id -> Net netidsNet := make(map[int64]*schema.Net) for _, net := range js2.Data { net := net netidsNet[net.ID] = &net } // Make unique ASNs. asns := make(map[int64]*pb.PeeringDBMember) for _, netixlan := range js.Data { member, ok := asns[netixlan.ASN] if !ok { asns[netixlan.ASN] = &pb.PeeringDBMember{ Asn: netixlan.ASN, Name: netidsNet[netixlan.NetID].Name, Routers: []*pb.PeeringDBMember_Router{}, } member = asns[netixlan.ASN] } member.Routers = append(member.Routers, &pb.PeeringDBMember_Router{ Ipv4: netixlan.IPv4, Ipv6: netixlan.IPv6, }) } // Build joined response. res := &pb.GetIXMembersResponse{ Members: make([]*pb.PeeringDBMember, len(asns)), } i = 0 for _, member := range asns { res.Members[i] = member i += 1 } return res, nil } func main() { flag.Parse() mi := mirko.New() if err := mi.Listen(); err != nil { glog.Exitf("Listen failed: %v", err) } s := &service{} pb.RegisterPeeringDBProxyServer(mi.GRPC(), s) if err := mi.Serve(); err != nil { glog.Exitf("Serve failed: %v", err) } <-mi.Done() }