blob: 1cbd2d7d11b31ea818b9cab22f278afecd3074ee [file] [log] [blame]
Sergiusz Bazanski1fad2e52019-08-01 20:16:27 +02001package model
2
3import (
4 "context"
5 "database/sql"
6 "fmt"
Serge Bazanskiec71cb52019-08-22 18:13:13 +02007 "net"
8 "strconv"
Sergiusz Bazanski1fad2e52019-08-01 20:16:27 +02009)
10
11func (m *sqlModel) ConfigureMissingSessions(ctx context.Context, gen func() SessionConfig) error {
12 tx := m.db.MustBeginTx(ctx, &sql.TxOptions{})
13 defer tx.Rollback()
14
15 q := `
16 SELECT
17 peer_routers.peer_id "peer_id",
18 peer_routers.id "id"
19 FROM peer_routers
20 WHERE peer_routers.id NOT IN (
21 SELECT session_configs.peer_router_id
22 FROM session_configs
23 )
24 `
25 missing := []struct {
26 PeerID string `db:"peer_id"`
27 ID string `db:"id"`
28 }{}
29 if err := m.db.SelectContext(ctx, &missing, q); err != nil {
30 return fmt.Errorf("SELECT peerRouters: %v", err)
31 }
32
33 for _, m := range missing {
34 config := gen()
35 q = `
36 INSERT INTO
37 session_configs
38 (peer_id, peer_router_id, bgp_secret)
39 VALUES
40 (:peer_id, :peer_router_id, :bgp_secret)
41 `
42 data := sqlSessionConfig{
43 PeerID: m.PeerID,
44 PeerRouterID: m.ID,
45 BGPSecret: config.BGPSecret,
46 }
47 if _, err := tx.NamedExecContext(ctx, q, data); err != nil {
48 return err
49 }
50 }
51
52 return tx.Commit()
53}
Serge Bazanskiec71cb52019-08-22 18:13:13 +020054
55func (m *sqlModel) GetPeerConfiguration(ctx context.Context) ([]*PeerConfiguration, error) {
56 q := `
57 SELECT
58 peers.asn "asn",
59 peer_pgp_keys.fingerprint "peer_pgp_keys.fingerprint",
60 peer_routers.v6 "peer_routers.v6", peer_routers.v4 "peer_routers.v4",
61 session_configs.bgp_secret "session_configs.bgp_secret"
62 FROM session_configs
63 LEFT JOIN peer_routers
64 ON peer_routers.id = session_configs.peer_router_id
65 INNER JOIN peer_pgp_keys
66 ON peer_pgp_keys.peer_id = session_configs.peer_id
67 LEFT JOIN peers
68 on peers.id = session_configs.peer_id
69 `
70
71 data := []struct {
72 PGP sqlPeerPGPKey `db:"peer_pgp_keys"`
73 Config sqlSessionConfig `db:"session_configs"`
74 Router sqlPeerRouter `db:"peer_routers"`
75 ASN string `db:"asn"`
76 }{}
77
78 if err := m.db.SelectContext(ctx, &data, q); err != nil {
79 return nil, fmt.Errorf("SELECT peers/peer_pgp_keys/session_configs: %v", err)
80 }
81
82 resM := make(map[string]*PeerConfiguration)
83
84 for _, d := range data {
85 k := fmt.Sprintf("%s", d.ASN)
86 r, ok := resM[k]
87 if !ok {
88 asn, err := strconv.ParseInt(d.ASN, 10, 64)
89 if err != nil {
90 return nil, fmt.Errorf("data corruption: invalid ASN %q", d.ASN)
91 }
92 r = &PeerConfiguration{
93 Peer: Peer{
94 ASN: asn,
95 Routers: []*Router{},
96 },
97 Key: PeerPGPKey{
98 PeerASN: asn,
99 Fingerprint: d.PGP.Fingerprint,
100 },
101 }
102 resM[k] = r
103 }
104
105 v6 := net.ParseIP(d.Router.V6.String)
106 v4 := net.ParseIP(d.Router.V4.String)
107 secret := d.Config.BGPSecret
108 r.Peer.Routers = append(r.Peer.Routers, &Router{
109 V6: v6,
110 V4: v4,
111 Config: &SessionConfig{
112 BGPSecret: secret,
113 },
114 })
115 }
116
117 res := make([]*PeerConfiguration, len(resM))
118 i := 0
119 for _, pc := range resM {
120 res[i] = pc
121 i += 1
122 }
123
124 return res, nil
125}