feat: implement AS holder name resolution and enhance ASEntry structure. Add ASHolderName function to retrieve organization names from RIPEstat, update ASEntry model to include ASN name, prefix count, and resolution timestamp. Modify database interactions and API responses to support new fields, improving ASN metadata handling.
CI / changes (push) Successful in 5s
CI / openapi (push) Has been skipped
CI / go (push) Successful in 24s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, , evobgp-web) (push) Successful in 1m9s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, evobgp-all, evobgp-web-all) (push) Successful in 1m3s
CI / docker-bird (push) Has been skipped
CI / bird2 (push) Successful in 16s
CI / docker-go (deploy/docker/evobgp-agent/Dockerfile, , evobgp-agent) (push) Successful in 1m0s
CI / docker-go (evobgp-all, 1, deploy/docker/gobinary/Dockerfile, , evobgp-all) (push) Successful in 1m37s
CI / docker-go (evobgp-api, 1, deploy/docker/gobinary/Dockerfile, , evobgp-api) (push) Successful in 1m25s
CI / docker-go (evobgp-deploy, 0, deploy/docker/gobinary/Dockerfile, , evobgp-deploy) (push) Successful in 1m29s
CI / docker-go (evobgp-ingest, 0, deploy/docker/gobinary/Dockerfile, , evobgp-ingest) (push) Successful in 1m25s
CI / docker-go (evobgp-node, 0, deploy/docker/gobinary/Dockerfile, , evobgp-node) (push) Successful in 1m21s
CI / docker-go (evobgp-render, 0, deploy/docker/gobinary/Dockerfile, , evobgp-render) (push) Successful in 1m24s
CI / docker-go (evobgp-scheduler, 0, deploy/docker/gobinary/Dockerfile, , evobgp-scheduler) (push) Successful in 1m31s
CI / changes (push) Successful in 5s
CI / openapi (push) Has been skipped
CI / go (push) Successful in 24s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, , evobgp-web) (push) Successful in 1m9s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, evobgp-all, evobgp-web-all) (push) Successful in 1m3s
CI / docker-bird (push) Has been skipped
CI / bird2 (push) Successful in 16s
CI / docker-go (deploy/docker/evobgp-agent/Dockerfile, , evobgp-agent) (push) Successful in 1m0s
CI / docker-go (evobgp-all, 1, deploy/docker/gobinary/Dockerfile, , evobgp-all) (push) Successful in 1m37s
CI / docker-go (evobgp-api, 1, deploy/docker/gobinary/Dockerfile, , evobgp-api) (push) Successful in 1m25s
CI / docker-go (evobgp-deploy, 0, deploy/docker/gobinary/Dockerfile, , evobgp-deploy) (push) Successful in 1m29s
CI / docker-go (evobgp-ingest, 0, deploy/docker/gobinary/Dockerfile, , evobgp-ingest) (push) Successful in 1m25s
CI / docker-go (evobgp-node, 0, deploy/docker/gobinary/Dockerfile, , evobgp-node) (push) Successful in 1m21s
CI / docker-go (evobgp-render, 0, deploy/docker/gobinary/Dockerfile, , evobgp-render) (push) Successful in 1m24s
CI / docker-go (evobgp-scheduler, 0, deploy/docker/gobinary/Dockerfile, , evobgp-scheduler) (push) Successful in 1m31s
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"evobgp/internal/store"
|
||||
|
||||
@@ -164,7 +165,8 @@ func (p *Postgres) ListASEntries(tenantID, moduleID string) ([]*store.ASEntry, e
|
||||
}
|
||||
ctx := context.Background()
|
||||
rows, err := p.pool.Query(ctx, `
|
||||
SELECT id::text, asn, community_id::text FROM module_as_entry WHERE module_id=$1`, moduleID)
|
||||
SELECT id::text, asn, community_id::text, asn_name, prefix_count, asn_resolved_at
|
||||
FROM module_as_entry WHERE module_id=$1 ORDER BY asn`, moduleID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -173,11 +175,18 @@ func (p *Postgres) ListASEntries(tenantID, moduleID string) ([]*store.ASEntry, e
|
||||
for rows.Next() {
|
||||
var e store.ASEntry
|
||||
e.ModuleID = moduleID
|
||||
var comm *string
|
||||
if err := rows.Scan(&e.ID, &e.ASN, &comm); err != nil {
|
||||
var comm, asnName *string
|
||||
var pc *int64
|
||||
var at *time.Time
|
||||
if err := rows.Scan(&e.ID, &e.ASN, &comm, &asnName, &pc, &at); err != nil {
|
||||
continue
|
||||
}
|
||||
e.CommunityID = strOrNil(comm)
|
||||
if asnName != nil {
|
||||
e.ASNName = *asnName
|
||||
}
|
||||
e.PrefixCount = pc
|
||||
e.ASNResolvedAt = at
|
||||
out = append(out, &e)
|
||||
}
|
||||
return out, nil
|
||||
@@ -209,14 +218,22 @@ func (p *Postgres) CreateASEntry(tenantID, moduleID string, in *store.ASEntry) (
|
||||
func (p *Postgres) getASEntry(ctx context.Context, moduleID, id string) (*store.ASEntry, error) {
|
||||
var e store.ASEntry
|
||||
e.ModuleID = moduleID
|
||||
var comm *string
|
||||
var comm, asnName *string
|
||||
var pc *int64
|
||||
var at *time.Time
|
||||
err := p.pool.QueryRow(ctx, `
|
||||
SELECT id::text, asn, community_id::text FROM module_as_entry WHERE id=$1 AND module_id=$2`, id, moduleID).Scan(
|
||||
&e.ID, &e.ASN, &comm)
|
||||
SELECT id::text, asn, community_id::text, asn_name, prefix_count, asn_resolved_at
|
||||
FROM module_as_entry WHERE id=$1 AND module_id=$2`, id, moduleID).Scan(
|
||||
&e.ID, &e.ASN, &comm, &asnName, &pc, &at)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
e.CommunityID = strOrNil(comm)
|
||||
if asnName != nil {
|
||||
e.ASNName = *asnName
|
||||
}
|
||||
e.PrefixCount = pc
|
||||
e.ASNResolvedAt = at
|
||||
return &e, nil
|
||||
}
|
||||
|
||||
@@ -231,6 +248,7 @@ func (p *Postgres) UpdateASEntry(tenantID, moduleID, entryID string, patch *stor
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
prevASN := cur.ASN
|
||||
if patch.ASN != nil {
|
||||
cur.ASN = *patch.ASN
|
||||
}
|
||||
@@ -245,17 +263,51 @@ func (p *Postgres) UpdateASEntry(tenantID, moduleID, entryID string, patch *stor
|
||||
if !store.ValidASN(cur.ASN) {
|
||||
return nil, store.ErrInvalidInput
|
||||
}
|
||||
clearResolve := patch.ASN != nil && cur.ASN != prevASN
|
||||
ctx := context.Background()
|
||||
_, err = p.pool.Exec(ctx, `
|
||||
UPDATE module_as_entry SET asn=$3, community_id=NULLIF($4::uuid, '00000000-0000-0000-0000-000000000000'::uuid), updated_at=now()
|
||||
WHERE id=$1 AND module_id=$2`,
|
||||
entryID, moduleID, cur.ASN, uuidOrNilPtr(cur.CommunityID))
|
||||
if clearResolve {
|
||||
_, err = p.pool.Exec(ctx, `
|
||||
UPDATE module_as_entry SET asn=$3, community_id=NULLIF($4::uuid, '00000000-0000-0000-0000-000000000000'::uuid),
|
||||
asn_name=NULL, prefix_count=NULL, asn_resolved_at=NULL, updated_at=now()
|
||||
WHERE id=$1 AND module_id=$2`,
|
||||
entryID, moduleID, cur.ASN, uuidOrNilPtr(cur.CommunityID))
|
||||
} else {
|
||||
_, err = p.pool.Exec(ctx, `
|
||||
UPDATE module_as_entry SET asn=$3, community_id=NULLIF($4::uuid, '00000000-0000-0000-0000-000000000000'::uuid), updated_at=now()
|
||||
WHERE id=$1 AND module_id=$2`,
|
||||
entryID, moduleID, cur.ASN, uuidOrNilPtr(cur.CommunityID))
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p.getASEntry(ctx, moduleID, entryID)
|
||||
}
|
||||
|
||||
func (p *Postgres) UpdateASEntryResolveMeta(tenantID, moduleID, entryID string, asnName string, prefixCount int64, resolvedAt time.Time) error {
|
||||
if _, err := p.GetModule(tenantID, moduleID); err != nil {
|
||||
return err
|
||||
}
|
||||
ctx := context.Background()
|
||||
var nameArg any
|
||||
sn := strings.TrimSpace(asnName)
|
||||
if sn == "" {
|
||||
nameArg = nil
|
||||
} else {
|
||||
nameArg = sn
|
||||
}
|
||||
tag, err := p.pool.Exec(ctx, `
|
||||
UPDATE module_as_entry SET asn_name=$3, prefix_count=$4, asn_resolved_at=$5, updated_at=now()
|
||||
WHERE id=$1 AND module_id=$2`,
|
||||
entryID, moduleID, nameArg, prefixCount, resolvedAt.UTC())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if tag.RowsAffected() == 0 {
|
||||
return store.ErrNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Postgres) DeleteASEntry(tenantID, moduleID, entryID string) error {
|
||||
if _, err := p.GetModule(tenantID, moduleID); err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user