blob: 5b09b9f570070c93233bf9908b371c06c9c4f03a [file] [log] [blame]
Sergiusz Bazanski6eaaaf92019-08-02 01:25:31 +02001package provider
2
3// Support for the RIPE IRR.
4// We use the RIPE REST DB API.
5
6import (
7 "context"
8 "encoding/json"
9 "fmt"
10 "io/ioutil"
11 "net/http"
12
13 pb "code.hackerspace.pl/hscloud/bgpwtf/cccampix/proto"
14)
15
16type ripeResponse struct {
17 Objects struct {
18 Object []ripeObject `json:"object"`
19 } `json:"objects"`
20}
21
22type ripeObject struct {
23 Type string `json:"type"`
24 Attributes struct {
25 Attribute []ripeAttribute `json:"attribute"`
26 } `json:"attributes"`
27}
28
29type ripeAttribute struct {
30 Name string `json:"name"`
31 Value string `json:"value"`
32}
33
34type ripe struct {
35}
36
37func NewRIPE() Provider {
38 return &ripe{}
39}
40
41func (r *ripe) Query(ctx context.Context, as uint64) (*pb.IRRQueryResponse, error) {
42 req, err := http.NewRequest("GET", fmt.Sprintf("http://rest.db.ripe.net/ripe/aut-num/AS%d.json", as), nil)
43 if err != nil {
44 return nil, err
45 }
46
47 req = req.WithContext(ctx)
48 client := http.DefaultClient
49
50 res, err := client.Do(req)
51 if err != nil {
52 return nil, fmt.Errorf("could not run GET to RIPE: %v", err)
53 }
54 defer res.Body.Close()
55 bytes, err := ioutil.ReadAll(res.Body)
56 if err != nil {
57 return nil, fmt.Errorf("could not read response from RIPE: %v", err)
58 }
59
60 data := ripeResponse{}
61 err = json.Unmarshal(bytes, &data)
62 if err != nil {
63 return nil, fmt.Errorf("could not decode response from RIPE: %v", err)
64 }
65
66 if len(data.Objects.Object) != 1 {
67 return nil, fmt.Errorf("could not retriev aut-num from RIPE")
68 }
69
70 attributes := make([]rpslRawAttribute, len(data.Objects.Object[0].Attributes.Attribute))
71
72 for i, attr := range data.Objects.Object[0].Attributes.Attribute {
73 attributes[i].name = attr.Name
74 attributes[i].value = attr.Value
75 }
76
77 return &pb.IRRQueryResponse{
78 Source: pb.IRRQueryResponse_SOURCE_RIPE,
79 Attributes: parseAttributes(attributes),
80 }, nil
81}