From e2797360f4b34523a403f6cde0ec8fcf4095e46d Mon Sep 17 00:00:00 2001 From: Dmitri Dolguikh Date: Mon, 3 Aug 2026 14:32:54 +0200 Subject: [PATCH] support for applied zone candidates Signed-off-by: Dmitri Dolguikh --- .../internals/network_map_db/db_store.go | 2 +- .../internals/network_map_db/pgsql/dns.go | 33 +++++++++++----- .../network_map_db/pgsql/group_test.go | 2 +- .../network_map_db/pgsql/network_map_data.go | 39 ++++++++++--------- 4 files changed, 46 insertions(+), 30 deletions(-) diff --git a/management/internals/network_map_db/db_store.go b/management/internals/network_map_db/db_store.go index 5278189f9..7c1a8e58e 100644 --- a/management/internals/network_map_db/db_store.go +++ b/management/internals/network_map_db/db_store.go @@ -29,7 +29,7 @@ type NetworkMapDBStore interface { GetNetworkResources(ctx context.Context, accountId string) ([]nmdata.NetworkResource, error) GetNetworkRouters(ctx context.Context, accountId string) (map[string]map[string]*nmdata.NetworkRouter, error) GetNetwork(ctx context.Context, accountId string) (nmdata.Network, error) - GetAccountZones(ctx context.Context, accountId string) ([]nmdata.CustomZone, error) + GetAppliedZoneCandidates(ctx context.Context, accountId string) ([]networkmap.AppliedZoneCandidate, error) GetAccountSettings(ctx context.Context, accountId string) (nmdata.AccountSettingsInfo, error) GetPostureChecks(ctx context.Context, accountId string) ([]nmdata.PostureChecks, error) GetNetworkMapData(ctx context.Context, accountId string) (*networkmap.NetworkMapData, error) diff --git a/management/internals/network_map_db/pgsql/dns.go b/management/internals/network_map_db/pgsql/dns.go index f22cc2569..182aeeeca 100644 --- a/management/internals/network_map_db/pgsql/dns.go +++ b/management/internals/network_map_db/pgsql/dns.go @@ -3,6 +3,7 @@ package networkmap_pgsql import ( "context" "database/sql" + "encoding/json" "errors" "fmt" "reflect" @@ -10,6 +11,7 @@ import ( "github.com/jackc/pgx/v5" "github.com/miekg/dns" networkmapdb "github.com/netbirdio/netbird/management/internals/network_map_db" + "github.com/netbirdio/netbird/shared/management/networkmap" "github.com/netbirdio/netbird/shared/management/networkmap/nmdata" ) @@ -17,7 +19,7 @@ var DnsUnsupportedRecordTypeError = errors.New("unsupported record type") const ( GetAccountZonesQuery = ` - select zones.id as id, domain, enable_search_domain as search_domain_disabled, + select zones.id as id, domain, enable_search_domain as search_domain_disabled, distribution_groups, r.name as record_name, r.type as record_type, 'IN' record_class, r.ttl as record_ttl, r.content as record_rdata from zones left join records as r on r.zone_id = zones.id @@ -25,15 +27,15 @@ const ( ` ) -func (pg *PgStore) GetAccountZones(ctx context.Context, accountId string) ([]nmdata.CustomZone, error) { +func (pg *PgStore) GetAppliedZoneCandidates(ctx context.Context, accountId string) ([]networkmap.AppliedZoneCandidate, error) { c, err := pg.Pool.Acquire(ctx) if err != nil { return nil, err } - return GetAccountZonesViaPgxConnection(ctx, c.Conn(), accountId) + return GetAppliedZoneCandidatesViaPgxConnection(ctx, c.Conn(), accountId) } -func GetAccountZonesViaPgxConnection(ctx context.Context, conn *pgx.Conn, accountId string) ([]nmdata.CustomZone, error) { +func GetAppliedZoneCandidatesViaPgxConnection(ctx context.Context, conn *pgx.Conn, accountId string) ([]networkmap.AppliedZoneCandidate, error) { rows, err := conn.Query(ctx, GetAccountZonesQuery, accountId) if err != nil { return nil, err @@ -44,7 +46,7 @@ func GetAccountZonesViaPgxConnection(ctx context.Context, conn *pgx.Conn, accoun return nil, err } - toret := make([]nmdata.CustomZone, 0, len(zones)) + toret := make([]networkmap.AppliedZoneCandidate, 0, len(zones)) currentZoneId := "" for _, z := range zones { zone := nmdata.CustomZone{} @@ -54,6 +56,11 @@ func GetAccountZonesViaPgxConnection(ctx context.Context, conn *pgx.Conn, accoun return nil, err } + var distributionGroups []string + if err := json.Unmarshal(z.DistributionGroups, &distributionGroups); err != nil { + return nil, err + } + rtype, rdata, err := recordTypeAndRdata(z.RecordType.String, z.RecordRData.String) if err != nil { return nil, err @@ -68,25 +75,26 @@ func GetAccountZonesViaPgxConnection(ctx context.Context, conn *pgx.Conn, accoun zone.Records = []nmdata.SimpleRecord{record} if len(toret) == 0 { - toret = append(toret, zone) + toret = append(toret, appliedZoneCandidateFromZone(zone, distributionGroups)) currentZoneId = z.Id continue } if z.Id == currentZoneId { lastZone := &toret[len(toret)-1] - lastZone.Records = append(lastZone.Records, record) + lastZone.Zone.Records = append(lastZone.Zone.Records, record) continue } - toret = append(toret, zone) + toret = append(toret, appliedZoneCandidateFromZone(zone, distributionGroups)) currentZoneId = z.Id } return toret, nil } type zone struct { - Id string `nmap:"skip"` + Id string `nmap:"skip"` + DistributionGroups json.RawMessage `nmap:"skip"` Domain sql.NullString SearchDomainDisabled sql.NullBool RecordName sql.NullString `nmap:"skip"` @@ -108,3 +116,10 @@ func recordTypeAndRdata(t, rdata string) (int, string, error) { return 0, "", fmt.Errorf("record type: %s %w", t, DnsUnsupportedRecordTypeError) } } + +func appliedZoneCandidateFromZone(z nmdata.CustomZone, distributionGroups []string) networkmap.AppliedZoneCandidate { + return networkmap.AppliedZoneCandidate{ + DistributionGroups: distributionGroups, + Zone: z, + } +} diff --git a/management/internals/network_map_db/pgsql/group_test.go b/management/internals/network_map_db/pgsql/group_test.go index fdad86940..c62123af0 100644 --- a/management/internals/network_map_db/pgsql/group_test.go +++ b/management/internals/network_map_db/pgsql/group_test.go @@ -200,7 +200,7 @@ func TestGetAccountZones(t *testing.T) { // err = loadSQL(ctx, s.pool, initDb) //assert.NoError(t, err) - zones, err := s.GetAccountZones(ctx, "d4g66rjl0ubs73b2q3b0") //"ckd7ee2fic3c73dtendg") + zones, err := s.GetAppliedZoneCandidates(ctx, "d4g66rjl0ubs73b2q3b0") //"ckd7ee2fic3c73dtendg") assert.NoError(t, err) fmt.Print(zones) diff --git a/management/internals/network_map_db/pgsql/network_map_data.go b/management/internals/network_map_db/pgsql/network_map_data.go index f28a3144d..1320fbadc 100644 --- a/management/internals/network_map_db/pgsql/network_map_data.go +++ b/management/internals/network_map_db/pgsql/network_map_data.go @@ -18,10 +18,10 @@ func (pg *PgStore) GetNetworkMapData(ctx context.Context, accountId string) (*ne if err != nil { return rollbackAndReturnError(ctx, tx, err) } - // dnsZones, err := GetAccountZonesViaPgxConnection(ctx, tx.Conn(), accountId) - // if err != nil { - // return rollbackAndReturnError(ctx, tx, err) - // } + dnsZones, err := GetAppliedZoneCandidatesViaPgxConnection(ctx, tx.Conn(), accountId) + if err != nil { + return rollbackAndReturnError(ctx, tx, err) + } groups, resourceToGroupIdx, err := GetGroupsViaPgxConnection(ctx, tx.Conn(), accountId) if err != nil { return rollbackAndReturnError(ctx, tx, err) @@ -102,21 +102,22 @@ func (pg *PgStore) GetNetworkMapData(ctx context.Context, accountId string) (*ne } toret := networkmap.NetworkMapData{ - AccountSettings: &acctSettings, - DNSSettings: &dnsSettings, - Network: &network, - Peers: toMap(peers, func(p nmdata.Peer) string { return p.ID }), - Groups: toMap(groups, func(g nmdata.Group) string { return g.PublicID }), - Policies: toSliceOfPtrs(policies), - ResourcePolicies: resourcePolicies, - Routes: toSliceOfPtrs(routes), - Routers: routers, - NameServerGroups: toSliceOfPtrs(nsGroups), - NetworkResources: toSliceOfPtrs(networkResources), - PostureChecks: toMap(postureChecks, func(pc nmdata.PostureChecks) string { return pc.ID }), - AllowedUserIDs: allowedUserIds, - GroupIDToUserIDs: groupsToUserIds, - NetworkXIDToPublicID: networkXIDToPublicID, // TODO (dmitri) maybe we can switch to public ids everywhere? + AccountSettings: &acctSettings, + DNSSettings: &dnsSettings, + Network: &network, + Peers: toMap(peers, func(p nmdata.Peer) string { return p.ID }), + Groups: toMap(groups, func(g nmdata.Group) string { return g.PublicID }), + Policies: toSliceOfPtrs(policies), + ResourcePolicies: resourcePolicies, + Routes: toSliceOfPtrs(routes), + Routers: routers, + NameServerGroups: toSliceOfPtrs(nsGroups), + NetworkResources: toSliceOfPtrs(networkResources), + PostureChecks: toMap(postureChecks, func(pc nmdata.PostureChecks) string { return pc.ID }), + AllowedUserIDs: allowedUserIds, + GroupIDToUserIDs: groupsToUserIds, + NetworkXIDToPublicID: networkXIDToPublicID, // TODO (dmitri) maybe we can switch to public ids everywhere? + AppliedZoneCandidates: dnsZones, } return &toret, nil