forked from hswaw/hscloud
115 lines
2.4 KiB
Go
115 lines
2.4 KiB
Go
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()
|
|
}
|