blob: a7f019960b9d76839d20597eac62037bc9fea646 [file] [log] [blame]
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()
}