blob: 1cbd2d7d11b31ea818b9cab22f278afecd3074ee [file] [log] [blame]
package model
import (
"context"
"database/sql"
"fmt"
"net"
"strconv"
)
func (m *sqlModel) ConfigureMissingSessions(ctx context.Context, gen func() SessionConfig) error {
tx := m.db.MustBeginTx(ctx, &sql.TxOptions{})
defer tx.Rollback()
q := `
SELECT
peer_routers.peer_id "peer_id",
peer_routers.id "id"
FROM peer_routers
WHERE peer_routers.id NOT IN (
SELECT session_configs.peer_router_id
FROM session_configs
)
`
missing := []struct {
PeerID string `db:"peer_id"`
ID string `db:"id"`
}{}
if err := m.db.SelectContext(ctx, &missing, q); err != nil {
return fmt.Errorf("SELECT peerRouters: %v", err)
}
for _, m := range missing {
config := gen()
q = `
INSERT INTO
session_configs
(peer_id, peer_router_id, bgp_secret)
VALUES
(:peer_id, :peer_router_id, :bgp_secret)
`
data := sqlSessionConfig{
PeerID: m.PeerID,
PeerRouterID: m.ID,
BGPSecret: config.BGPSecret,
}
if _, err := tx.NamedExecContext(ctx, q, data); err != nil {
return err
}
}
return tx.Commit()
}
func (m *sqlModel) GetPeerConfiguration(ctx context.Context) ([]*PeerConfiguration, error) {
q := `
SELECT
peers.asn "asn",
peer_pgp_keys.fingerprint "peer_pgp_keys.fingerprint",
peer_routers.v6 "peer_routers.v6", peer_routers.v4 "peer_routers.v4",
session_configs.bgp_secret "session_configs.bgp_secret"
FROM session_configs
LEFT JOIN peer_routers
ON peer_routers.id = session_configs.peer_router_id
INNER JOIN peer_pgp_keys
ON peer_pgp_keys.peer_id = session_configs.peer_id
LEFT JOIN peers
on peers.id = session_configs.peer_id
`
data := []struct {
PGP sqlPeerPGPKey `db:"peer_pgp_keys"`
Config sqlSessionConfig `db:"session_configs"`
Router sqlPeerRouter `db:"peer_routers"`
ASN string `db:"asn"`
}{}
if err := m.db.SelectContext(ctx, &data, q); err != nil {
return nil, fmt.Errorf("SELECT peers/peer_pgp_keys/session_configs: %v", err)
}
resM := make(map[string]*PeerConfiguration)
for _, d := range data {
k := fmt.Sprintf("%s", d.ASN)
r, ok := resM[k]
if !ok {
asn, err := strconv.ParseInt(d.ASN, 10, 64)
if err != nil {
return nil, fmt.Errorf("data corruption: invalid ASN %q", d.ASN)
}
r = &PeerConfiguration{
Peer: Peer{
ASN: asn,
Routers: []*Router{},
},
Key: PeerPGPKey{
PeerASN: asn,
Fingerprint: d.PGP.Fingerprint,
},
}
resM[k] = r
}
v6 := net.ParseIP(d.Router.V6.String)
v4 := net.ParseIP(d.Router.V4.String)
secret := d.Config.BGPSecret
r.Peer.Routers = append(r.Peer.Routers, &Router{
V6: v6,
V4: v4,
Config: &SessionConfig{
BGPSecret: secret,
},
})
}
res := make([]*PeerConfiguration, len(resM))
i := 0
for _, pc := range resM {
res[i] = pc
i += 1
}
return res, nil
}