blob: a7f019960b9d76839d20597eac62037bc9fea646 [file] [log] [blame]
Sergiusz Bazanskie653e6a2019-07-20 16:36:00 +02001package main
2
3import (
4 "context"
5 "flag"
6
7 "github.com/golang/glog"
8 "google.golang.org/grpc/codes"
9 "google.golang.org/grpc/status"
10
11 "code.hackerspace.pl/hscloud/bgpwtf/cccampix/peeringdb/schema"
12 pb "code.hackerspace.pl/hscloud/bgpwtf/cccampix/proto"
13 "code.hackerspace.pl/hscloud/go/mirko"
14)
15
16type service struct {
17}
18
19func (s *service) GetIXMembers(ctx context.Context, req *pb.GetIXMembersRequest) (*pb.GetIXMembersResponse, error) {
20 if req.Id == 0 {
21 return nil, status.Error(codes.InvalidArgument, "IX id must be given")
22 }
23
24 // First, get netixlans (membership info) for the given IX.
25 js := struct {
26 Data []schema.NetIXLan `json:"Data"`
27 }{}
28 err := schema.Get(ctx, &js, schema.NetIXLanInIXURL(req.Id))
29 if err != nil {
30 return nil, status.Errorf(codes.Unavailable, "PeeringDB query error: %v", err)
31 }
32
33 // Build set of seen Nets/ASs.
34 netids := make(map[int64]bool)
35 for _, netixlan := range js.Data {
36 netids[netixlan.NetID] = true
37 }
38
39 // Convert set to unique list.
40 nets := make([]int64, len(netids))
41 i := 0
42 for id, _ := range netids {
43 nets[i] = id
44 i += 1
45 }
46
47 // Request information about nets/ASNs:
48 js2 := struct {
49 Data []schema.Net `json:"Data"`
50 }{}
51 err = schema.Get(ctx, &js2, schema.NetURLMulti(nets))
52 if err != nil {
53 return nil, status.Errorf(codes.Unavailable, "PeeringDB query error: %v", err)
54 }
55
56 // Make map net id -> Net
57 netidsNet := make(map[int64]*schema.Net)
58 for _, net := range js2.Data {
59 net := net
60 netidsNet[net.ID] = &net
61 }
62
Sergiusz Bazanski0607aba2019-08-02 13:38:22 +020063 // Make unique ASNs.
64 asns := make(map[int64]*pb.PeeringDBMember)
65
66 for _, netixlan := range js.Data {
67 member, ok := asns[netixlan.ASN]
68 if !ok {
69 asns[netixlan.ASN] = &pb.PeeringDBMember{
70 Asn: netixlan.ASN,
71 Name: netidsNet[netixlan.NetID].Name,
72 Routers: []*pb.PeeringDBMember_Router{},
73 }
74 member = asns[netixlan.ASN]
75 }
76
77 member.Routers = append(member.Routers, &pb.PeeringDBMember_Router{
78 Ipv4: netixlan.IPv4,
79 Ipv6: netixlan.IPv6,
80 })
81 }
82
Sergiusz Bazanskie653e6a2019-07-20 16:36:00 +020083 // Build joined response.
84
85 res := &pb.GetIXMembersResponse{
Sergiusz Bazanski0607aba2019-08-02 13:38:22 +020086 Members: make([]*pb.PeeringDBMember, len(asns)),
Sergiusz Bazanskie653e6a2019-07-20 16:36:00 +020087 }
88
Sergiusz Bazanski0607aba2019-08-02 13:38:22 +020089 i = 0
90 for _, member := range asns {
91 res.Members[i] = member
92 i += 1
Sergiusz Bazanskie653e6a2019-07-20 16:36:00 +020093 }
94
95 return res, nil
96}
97
98func main() {
99 flag.Parse()
100 mi := mirko.New()
101
102 if err := mi.Listen(); err != nil {
103 glog.Exitf("Listen failed: %v", err)
104 }
105
106 s := &service{}
107 pb.RegisterPeeringDBProxyServer(mi.GRPC(), s)
108
109 if err := mi.Serve(); err != nil {
110 glog.Exitf("Serve failed: %v", err)
111 }
112
113 <-mi.Done()
114}