Files
EvoBGP/internal/store/backend.go
T
Denozordec c958d5af0d
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
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.
2026-04-06 01:49:31 +07:00

209 lines
8.6 KiB
Go

package store
import "time"
// Backend is the persistence abstraction for the control plane (memory, PostgreSQL, SQLite).
type Backend interface {
MaterializedPrefixStats() (max int, sum int)
PeerCount() int
PeerSessionCountsByState() map[string]int
// DemoIDs is non-empty only after SeedDemo (memory or seeded SQL).
DemoIDs() (tenant, moduleCDN, moduleIP, revision, speaker string)
// ListTenantIDs returns distinct tenant identifiers (for background workers).
ListTenantIDs() ([]string, error)
ListModules(tenantID string) []*Module
GetModule(tenantID, moduleID string) (*Module, error)
CreateModule(tenantID string, in *Module) (*Module, error)
UpdateModule(tenantID, moduleID string, patch *ModulePatch) (*Module, error)
SoftDeleteModule(tenantID, moduleID string) error
ListCDNSources(tenantID, moduleID string) ([]*CDNSource, error)
CreateCDNSource(tenantID, moduleID string, in *CDNSource) (*CDNSource, error)
UpdateCDNSource(tenantID, moduleID, sourceID string, patch *CDNSourcePatch) (*CDNSource, error)
DeleteCDNSource(tenantID, moduleID, sourceID string) error
ListASEntries(tenantID, moduleID string) ([]*ASEntry, error)
CreateASEntry(tenantID, moduleID string, in *ASEntry) (*ASEntry, error)
UpdateASEntry(tenantID, moduleID, entryID string, patch *ASEntryPatch) (*ASEntry, error)
DeleteASEntry(tenantID, moduleID, entryID string) error
// UpdateASEntryResolveMeta записывает имя AS, число объявленных префиксов и время успешного резолва (pipeline).
UpdateASEntryResolveMeta(tenantID, moduleID, entryID string, asnName string, prefixCount int64, resolvedAt time.Time) error
ListDomainEntries(tenantID, moduleID string) ([]*DomainEntry, error)
CreateDomainEntry(tenantID, moduleID string, in *DomainEntry) (*DomainEntry, error)
UpdateDomainEntry(tenantID, moduleID, entryID string, patch *DomainEntryPatch) (*DomainEntry, error)
DeleteDomainEntry(tenantID, moduleID, entryID string) error
ListIPRangeEntries(tenantID, moduleID string) ([]*IPRangeEntry, error)
CreateIPRangeEntry(tenantID, moduleID string, in *IPRangeEntry) (*IPRangeEntry, error)
UpdateIPRangeEntry(tenantID, moduleID, entryID string, patch *IPRangePatch) (*IPRangeEntry, error)
DeleteIPRangeEntry(tenantID, moduleID, entryID string) error
ListDohProfiles(tenantID string) ([]*DohProfile, error)
GetDohProfile(tenantID, id string) (*DohProfile, error)
CreateDohProfile(tenantID string, in *DohProfile) (*DohProfile, error)
UpdateDohProfile(tenantID, id string, patch *DohProfilePatch) (*DohProfile, error)
DeleteDohProfile(tenantID, id string) error
ListCommunities(tenantID string) ([]*Community, error)
GetCommunity(tenantID, id string) (*Community, error)
CreateCommunity(tenantID string, in *Community) (*Community, error)
UpdateCommunity(tenantID, id string, patch *CommunityPatch) (*Community, error)
DeleteCommunity(tenantID, id string) error
ListPeers(tenantID string) []*BGPPeer
GetPeer(tenantID, id string) (*BGPPeer, error)
CreatePeer(tenantID string, in *BGPPeer) (*BGPPeer, error)
UpdatePeer(tenantID, id string, patch *PeerPatch) (*BGPPeer, error)
DeletePeer(tenantID, id string) error
ListSpeakersForTenant(tenantID string) []*Speaker
GetSpeaker(tenantID, speakerID string) (*Speaker, error)
GetSpeakerAnyTenant(speakerID string) (*Speaker, error)
CreateSpeaker(tenantID string, in *Speaker) (*Speaker, error)
UpdateSpeaker(tenantID, id string, patch *SpeakerPatch) (*Speaker, error)
GetRevision(tenantID, revisionID string) (*Revision, error)
ListRevisions(tenantID, moduleID string, cursor string, limit int) (items []*Revision, nextCursor string, hasMore bool)
ListRevisionPrefixes(tenantID, revisionID string, cursor string, limit int) (prefixes []PrefixRow, next string, more bool)
CreateRollbackRevision(tenantID, sourceRevisionID string) (newID string, err error)
// CreateRenderRevision inserts a new config_revision (revID must be unique) with materialized prefixes and preview fragments.
CreateRenderRevision(revisionID, tenantID, moduleID string, parentRevisionID *string, contentHash string, previewFragments map[string]string, prefixes []PrefixRow) error
RevisionDiff(tenantID, aID, bID string) (map[string]any, error)
SetLastAppliedRevision(tenantID, speakerID, revisionID string) error
PublishRevisionForSpeaker(speakerID, revisionID string) error
LatestPublishedRevision(speakerID string) (revisionID string, publishedAt time.Time, err error)
ListGlobalSettings(tenantID string) (map[string]any, error)
PatchGlobalSettings(tenantID string, patch map[string]any) error
}
// ModulePatch is a partial update for module.
type ModulePatch struct {
Name *string `json:"name,omitempty"`
Enabled *bool `json:"enabled,omitempty"`
Priority *int `json:"priority,omitempty"`
RefreshIntervalSec *int `json:"refresh_interval_sec,omitempty"`
CronExpr *string `json:"cron_expr,omitempty"`
DefaultCommunityID *string `json:"default_community_id,omitempty"`
DohProfileID *string `json:"doh_profile_id,omitempty"`
}
// CDNSource is a row under a CDN module.
type CDNSource struct {
ID string `json:"id,omitempty"`
ModuleID string `json:"module_id,omitempty"`
SourceKind string `json:"source_kind"`
URL string `json:"url"`
Etag string `json:"etag"`
RefreshIntervalSec *int `json:"refresh_interval_sec"`
CommunityID *string `json:"community_id"`
}
type CDNSourcePatch struct {
SourceKind *string `json:"source_kind,omitempty"`
URL *string `json:"url,omitempty"`
Etag *string `json:"etag,omitempty"`
RefreshIntervalSec *int `json:"refresh_interval_sec,omitempty"`
CommunityID *string `json:"community_id,omitempty"`
}
type ASEntry struct {
ID string `json:"id,omitempty"`
ModuleID string `json:"module_id,omitempty"`
ASN int64 `json:"asn"`
CommunityID *string `json:"community_id"`
ASNName string `json:"asn_name,omitempty"`
PrefixCount *int64 `json:"prefix_count,omitempty"`
ASNResolvedAt *time.Time `json:"asn_resolved_at,omitempty"`
}
type ASEntryPatch struct {
ASN *int64 `json:"asn,omitempty"`
CommunityID *string `json:"community_id,omitempty"`
}
// ValidASN reports whether n is a usable BGP ASN (1..4294967295).
func ValidASN(n int64) bool {
return n >= 1 && n <= 4294967295
}
type DomainEntry struct {
ID string `json:"id,omitempty"`
ModuleID string `json:"module_id,omitempty"`
FQDN string `json:"fqdn"`
CommunityID *string `json:"community_id"`
}
type DomainEntryPatch struct {
FQDN *string `json:"fqdn,omitempty"`
CommunityID *string `json:"community_id,omitempty"`
}
type IPRangeEntry struct {
ID string `json:"id,omitempty"`
ModuleID string `json:"module_id,omitempty"`
Prefix string `json:"prefix"`
CommunityID *string `json:"community_id"`
}
type IPRangePatch struct {
Prefix *string `json:"prefix,omitempty"`
CommunityID *string `json:"community_id,omitempty"`
}
type DohProfile struct {
ID string `json:"id,omitempty"`
TenantID string `json:"tenant_id,omitempty"`
Name string `json:"name"`
URL string `json:"url"`
TimeoutMs *int `json:"timeout_ms"`
SecretRef *string `json:"vault_secret_ref"`
}
type DohProfilePatch struct {
Name *string `json:"name,omitempty"`
URL *string `json:"url,omitempty"`
TimeoutMs *int `json:"timeout_ms,omitempty"`
SecretRef *string `json:"vault_secret_ref,omitempty"`
}
type Community struct {
ID string `json:"id,omitempty"`
TenantID string `json:"tenant_id,omitempty"`
Name string `json:"name"`
Kind string `json:"kind"`
ValueJSON string `json:"value_json"`
}
type CommunityPatch struct {
Name *string `json:"name,omitempty"`
Kind *string `json:"kind,omitempty"`
ValueJSON *string `json:"value_json,omitempty"`
}
type PeerPatch struct {
Neighbor *string `json:"neighbor,omitempty"`
RemoteASN *int64 `json:"remote_asn,omitempty"`
SpeakerID *string `json:"bgp_speaker_id,omitempty"`
Enabled *bool `json:"enabled,omitempty"`
Name *string `json:"name,omitempty"`
SessionState *string `json:"session_state,omitempty"`
PoliciesJSON *string `json:"policies_json,omitempty"`
}
type SpeakerPatch struct {
Role *string `json:"role,omitempty"`
Endpoint *string `json:"endpoint,omitempty"`
MetaJSON *string `json:"meta_json,omitempty"`
}
// PrefixRow is one materialized prefix for GET /revisions/.../prefixes.
type PrefixRow struct {
Prefix string
CommunityID *string
Source string
}