bgpwtf/cccampix: draw the rest of the fucking owl
Change-Id: I49fd5906e69512e8f2d414f406edc0179522f225
diff --git a/bgpwtf/cccampix/verifier/model/model.go b/bgpwtf/cccampix/verifier/model/model.go
new file mode 100644
index 0000000..b9b81c9
--- /dev/null
+++ b/bgpwtf/cccampix/verifier/model/model.go
@@ -0,0 +1,141 @@
+package model
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "strings"
+ "time"
+
+ pb "code.hackerspace.pl/hscloud/bgpwtf/cccampix/proto"
+ "code.hackerspace.pl/hscloud/bgpwtf/cccampix/verifier/model/migrations"
+ migrate "github.com/golang-migrate/migrate/v4"
+ _ "github.com/golang-migrate/migrate/v4/database/cockroachdb"
+ "github.com/jmoiron/sqlx"
+ _ "github.com/lib/pq"
+)
+
+type Model interface {
+ MigrateUp() error
+
+ RecordPeeringDBPeers(ctx context.Context, members []*pb.PeeringDBMember) error
+ RecordPeeringDBPeerRouters(ctx context.Context, members []*pb.PeeringDBMember) error
+ GetPeeringDBPeer(ctx context.Context, asn int64) (*pb.PeeringDBMember, error)
+
+ GetCheckablePeers(ctx context.Context) ([]*Peer, error)
+ SubmitPeerCheckResults(ctx context.Context, res []*PeerCheckResult) error
+ GetPeerCheckResults(ctx context.Context, asn []int64) ([]*PeerCheckResult, error)
+
+ UpdatePGPKey(ctx context.Context, key *PeerPGPKey) error
+
+ ConfigureMissingSessions(ctx context.Context, gen func() SessionConfig) error
+
+ UpdateAllowedPrefixes(ctx context.Context, asn int64, prefixes []*AllowedPrefix) error
+ GetAllowedPrefixes(ctx context.Context, asn int64) ([]*AllowedPrefix, error)
+}
+
+type stringer struct {
+}
+
+func (s *stringer) String() string {
+ if s == nil {
+ return "<nil>"
+ }
+ return fmt.Sprintf("%+v", *s)
+}
+
+type Router struct {
+ stringer
+ V6 net.IP
+ V4 net.IP
+}
+
+type Peer struct {
+ stringer
+ ASN int64
+ Name string
+ Routers []*Router
+}
+
+type PeerCheckStatus int
+
+const (
+ PeerCheckStatus_Invalid PeerCheckStatus = iota
+ PeerCheckStatus_Okay
+ PeerCheckStatus_Failed
+ PeerCheckStatus_SoftFailed
+)
+
+type PeerCheckResult struct {
+ PeerASN int64
+ CheckName string
+ Time time.Time
+ Status PeerCheckStatus
+ Message string
+}
+
+func (p *PeerCheckResult) String() string {
+ if p == nil {
+ return "<nil>"
+ }
+ return fmt.Sprintf("%+v", *p)
+}
+
+type PeerPGPKey struct {
+ stringer
+ PeerASN int64
+ Fingerprint string
+}
+
+type SessionConfig struct {
+ BGPSecret string
+}
+
+type AllowedPrefix struct {
+ Prefix net.IPNet
+ MaxLength int64
+ TA string
+}
+
+func (p *AllowedPrefix) String() string {
+ if p == nil {
+ return "<nil>"
+ }
+ return fmt.Sprintf("%+v", *p)
+}
+
+type sqlModel struct {
+ db *sqlx.DB
+ dsn string
+}
+
+func Connect(ctx context.Context, driver, dsn string) (Model, error) {
+ if dsn == "" {
+ return nil, fmt.Errorf("dsn cannot be empty")
+ }
+
+ db, err := sqlx.ConnectContext(ctx, driver, dsn)
+ if err != nil {
+ return nil, fmt.Errorf("could not connect to database: %v", err)
+ }
+
+ return &sqlModel{
+ db: db,
+ dsn: dsn,
+ }, nil
+}
+
+func (m *sqlModel) MigrateUp() error {
+ dsn := "cockroach://" + strings.TrimPrefix(m.dsn, "postgres://")
+ mig, err := migrations.New(dsn)
+ if err != nil {
+ return err
+ }
+ err = mig.Up()
+ switch err {
+ case migrate.ErrNoChange:
+ return nil
+ default:
+ return err
+ }
+}