| 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() |
| } |