From 6ee0987cba7d9a0325332f268157f36ac2ad08b9 Mon Sep 17 00:00:00 2001 From: Dmitri Dolguikh Date: Mon, 17 Aug 2026 11:10:31 +0200 Subject: [PATCH] updated GetNetworkMapData test to verify all calls -- policies, routes, etc Signed-off-by: Dmitri Dolguikh --- .../network_map_db/network_map_data.sql | 98 ++++++ .../network_map_data_golden.json | 296 +++++++++++++----- .../network_map_db/network_map_data_test.go | 13 +- .../network_map_db/pgsql/pg_store.go | 5 + .../internals/network_map_db/shared_types.go | 1 + .../network_map_db/sqlite/sqlite_store.go | 5 + 6 files changed, 341 insertions(+), 77 deletions(-) create mode 100644 integration_tests/management/network_map_db/network_map_data.sql diff --git a/integration_tests/management/network_map_db/network_map_data.sql b/integration_tests/management/network_map_db/network_map_data.sql new file mode 100644 index 000000000..60cfd291e --- /dev/null +++ b/integration_tests/management/network_map_db/network_map_data.sql @@ -0,0 +1,98 @@ +insert into accounts (id, network_identifier, network_net, network_net_v6, network_dns, network_serial,dns_settings_disabled_management_groups, + settings_peer_login_expiration_enabled, settings_peer_login_expiration, settings_peer_inactivity_expiration_enabled, + settings_peer_inactivity_expiration, settings_dns_domain, settings_ipv6_enabled_groups, settings_routing_peer_dns_resolution_enabled, + settings_lazy_connection_enabled, settings_auto_update_version, settings_auto_update_always, settings_metrics_push_enabled) +VALUES('account-33','network-331','{"IP":"100.103.0.0","Mask":"//8AAA=="}','{"IP":"fdde:e995:fd38:a465::","Mask":"//////////8AAAAAAAAAAA=="}','',1,'["disabled-group-1","disabled-group-2"]', + true, 86400000000000, false, + 86400000000000, null, '["33-group-one-resource-id"]', false, + false, 'disabled', false, false); +insert into groups (id, account_id, name, resources, public_id) VALUES('33-group-one-resource-id','account-33','group-1-name', '[{"ID":"host-id-1","Type":"host"}]','group-one-resource-id-public'); +insert into groups (id, account_id, name, resources, public_id) VALUES('33-group-two-resources-id','account-33','group-2-name', '[{"ID":"subnet-id-1","Type":"subnet"}, {"ID":"host-id-2","Type":"host"}]','33-group-two-resources-id-public'); +insert into groups (id, account_id, name, resources, public_id) VALUES('33-group-no-resources-id','account-33','group-3-name', null,'33-group-no-resources-id-public'); +insert into group_peers (account_id, peer_id, group_id) VALUES('account-33','peer-id-331','33-group-one-resource-id'); +insert into group_peers (account_id, peer_id, group_id) VALUES('account-33','peer-id-332','33-group-two-resources-id'); +insert into group_peers (account_id, peer_id, group_id) VALUES('account-33','peer-id-333','33-group-two-resources-id'); +insert into peers (id, account_id, "key", ssh_key, dns_label, extra_dns_labels, user_id, ssh_enabled, login_expiration_enabled, last_login, ip, ipv6, + peer_status_requires_approval, peer_status_connected, proxy_meta_embedded, proxy_meta_cluster, + meta_wt_version, meta_go_os, meta_os_version, meta_kernel_version, meta_network_addresses, meta_files, + meta_capabilities, meta_flags, meta_sync_message_version, + location_country_code, location_city_name, location_connection_ip) + values('peer-id-331','account-33','key-331','ssh-key-1','peer-1','["extra-peer-1"]','user-id-1',true,true,'2026-08-06 13:25:59.12999','"10.10.10.1"','"fdf4:ba80:6aa5:89f1:44d7:8701:8699:4940"', + false,true,true,'cluster-1.netbird.services', + '0.76.0','linux','26.4.1','6.8.0-134-generic','[{"NetIP":"fe80::8b4c:973f:a76b:3771/64","Mac":"00:15:5d:24:0c:ac"},{"NetIP":"192.168.16.1/20","Mac":"00:15:5d:24:0c:ac"}]','[{"Path":"/usr/bin/netbird","Exist":false,"ProcessIsRunning":false}]', + '[1,2]','{"RosenpassEnabled":false,"RosenpassPermissive":false,"ServerSSHAllowed":true,"DisableClientRoutes":false,"DisableServerRoutes":false,"DisableDNS":false,"DisableFirewall":false,"BlockLANAccess":false,"BlockInbound":false,"DisableIPv6":false,"LazyConnectionEnabled":false}',1, + 'DE','Berlin','"46.201.148.187"'); +insert into peers (id,account_id,"key", ssh_key, dns_label, extra_dns_labels, user_id, ssh_enabled, login_expiration_enabled, last_login, ip, ipv6, + peer_status_requires_approval, peer_status_connected, proxy_meta_embedded, proxy_meta_cluster, + meta_wt_version, meta_go_os, meta_os_version, meta_kernel_version, meta_network_addresses, meta_files, + meta_capabilities, meta_flags, meta_sync_message_version, + location_country_code, location_city_name, location_connection_ip) + values('peer-id-332','account-33','key-332','ssh-key-2','peer-2','["extra-peer-2"]','user-id-2',true,true,'2026-08-06 14:25:59.12999','"10.10.100.1"','"fdf5:ba80:6aa5:89f1:44d7:8701:8699:4940"', + false,true,true,'cluster-2.netbird.services', + '0.76.1','linux','26.4.2','6.8.0-135-generic','[{"NetIP":"fe81::8b4c:973f:a76b:3771/64","Mac":"00:15:5d:24:0c:ad"},{"NetIP":"192.168.17.1/20","Mac":"00:15:5d:24:0c:ad"}]','[{"Path":"/usr/bin/netbird","Exist":false,"ProcessIsRunning":false}]', + '[1,2]','{"RosenpassEnabled":false,"RosenpassPermissive":false,"ServerSSHAllowed":true,"DisableClientRoutes":false,"DisableServerRoutes":false,"DisableDNS":false,"DisableFirewall":false,"BlockLANAccess":false,"BlockInbound":false,"DisableIPv6":false,"LazyConnectionEnabled":false}',0, + 'DE','Berlin','"46.201.149.187"'); +insert into peers (id,account_id,"key", ssh_key, dns_label, extra_dns_labels, user_id, ssh_enabled, login_expiration_enabled, last_login, ip, ipv6, + peer_status_requires_approval, peer_status_connected, proxy_meta_embedded, proxy_meta_cluster, + meta_wt_version, meta_go_os, meta_os_version, meta_kernel_version, meta_network_addresses, meta_files, + meta_capabilities, meta_flags, meta_sync_message_version, + location_country_code, location_city_name, location_connection_ip) + values('peer-id-333','account-33','key-333','ssh-key-3','peer-3','["extra-peer-3"]','user-id-3',true,true,'2026-08-06 12:25:59.12999','"10.10.200.1"','"fdf6:ba80:6aa5:89f1:44d7:8701:8699:4940"', + false,true,true,'cluster-3.netbird.services', + '0.76.2','linux','26.4.3','6.8.0-136-generic','[{"NetIP":"fe82::8b4c:973f:a76b:3771/64","Mac":"00:15:5d:24:0c:ae"},{"NetIP":"192.168.18.1/20","Mac":"00:15:5d:24:0c:ae"}]','[{"Path":"/usr/bin/netbird","Exist":false,"ProcessIsRunning":false}]', + '[1,2]','{"RosenpassEnabled":false,"RosenpassPermissive":false,"ServerSSHAllowed":true,"DisableClientRoutes":false,"DisableServerRoutes":false,"DisableDNS":false,"DisableFirewall":false,"BlockLANAccess":false,"BlockInbound":false,"DisableIPv6":false,"LazyConnectionEnabled":false}',1, + 'DE','Berlin','"46.201.150.187"'); + +insert into zones (id, account_id, domain, enable_search_domain, distribution_groups) + VALUES('zone-331','account-33','test-331.com',true,'["33-group-one-resource-id"]'); +insert into records (id, account_id, zone_id, name, type, ttl, content) + VALUES('record-331','account-33','zone-331','test.test-331.com','A',1800,'1.1.1.1'); +insert into records (id, account_id, zone_id, name, type, ttl, content) + VALUES('record-332','account-33','zone-331','test2.test-331.com','A',1800,'1.1.1.2'); + +insert into domains (id, account_id, domain, target_cluster) + VALUES('domain-331','account-33','test-331.com','target-1.cluster.local'); + +insert into name_server_groups (id, public_id, name, description, name_servers, groups, domains, enabled, search_domains_enabled, "primary", account_id) + VALUES('nsgroup-331','nsgroup-1-public','nsgroup-1','nsgroup-1','[{"IP":"192.168.31.2","NSType":1,"Port":53}]','["33-group-one-resource-id"]','["test-1.com"]',TRUE,FALSE,TRUE,'account-33'); +insert into name_server_groups (id, public_id, name, description, name_servers, groups, domains, enabled, search_domains_enabled,"primary",account_id) + VALUES('nsgroup-332','nsgroup-2-public','nsgroup-2','nsgroup-2','[{"IP":"192.168.32.3","NSType":1,"Port":53}]','["33-group-one-resource-id","33-group-no-resources-id"]','["test-1.com","test-2.com"]',TRUE,FALSE,TRUE,'account-33'); + +insert into network_resources (id, account_id, network_id, public_id, name, description, type, domain, prefix, enabled) + VALUES('net-resource-331','account-33','network-331','net-resource-public-1','network-resource-1','network-resource-1','subnet','','"10.0.0.0/16"',TRUE); +insert into network_resources (id, account_id, network_id, public_id, name, description, type, domain, prefix, enabled) + VALUES('net-resource-332','account-33','network-332','net-resource-public-2','network-resource-2','network-resource-2','domain','test.com','',TRUE); + +insert into network_routers (id, account_id, public_id, peer, network_id, masquerade, metric, enabled, peer_groups) + VALUES('test-nr-id-331','account-33','public-id-1','peer-id-331','network-id-1',TRUE,999,TRUE,'["33-group-one-resource-id"]'); +insert into network_routers (id, account_id, public_id, peer, network_id, masquerade, metric, enabled, peer_groups) + VALUES('test-nr-id-332','account-33','public-id-2','','network-id-2',TRUE,333,TRUE,'["33-group-two-resources-id","33-group-no-resources-id"]'); + +insert into networks (id, account_id, public_id) VALUES('network-331','account-33','network-1-public'); +insert into networks (id, account_id, public_id) VALUES('network-332','account-33','network-2-public'); + +insert into policies (id, public_id, account_id, enabled, source_posture_checks) + values('policy-331','policy-1-public','account-33',true,'["posture-checks-1","posture-checks-2"]'); +insert into policy_rules (id, policy_id, enabled, action, protocol, bidirectional, sources, destinations, + source_resource, destination_resource, ports, port_ranges, + authorized_groups, authorized_user) + values('policy-331-rule-1','policy-331',true,'accept','tcp',true,'["33-group-one-resource-id","33-group-two-resources-id"]','["33-group-one-resource-id","33-group-two-resources-id"]', + '{"ID":"host-id-1","Type":"host"}','{"ID":"domain-331","Type":"domain"}','["8080","8443"]', '[{"Start":8080,"End":8090}]', + '{"33-group-one-resource-id":["user-1", "user-2"]}','user-3'); + +insert into posture_checks (id, account_id, public_id, checks) + VALUES('posturecheck-331','account-33','posturecheck-1-public', + '{"NBVersionCheck":{"MinVersion":"0.25.0"}, + "OSVersionCheck":{"Darwin":{"MinVersion":"12.0"}}, + "GeoLocationCheck":{"Locations":[{"CountryCode":"FI","CityName":""}],"Action":"allow"}, + "PeerNetworkRangeCheck":{"Action":"deny","Ranges":["192.168.0.1/24"]}}'); + +insert into routes (id, account_id, public_id, network, domains, keep_route, net_id, description, + peer, peer_groups, network_type, masquerade, metric, enabled, + groups, access_control_groups, skip_auto_apply) + VALUES('route-331','account-33','route-1-public','"172.0.0.0/16"','["test-1.com"]',true,'route-331-net-id','route-1', + 'peer-id-331','["33-group-one-resource-id"]',1,true,9999,true, + '["33-group-one-resource-id"]','["33-group-one-resource-id"]',false); + +insert into services (id, account_id, enabled, private, access_groups, proxy_cluster, domain) + values('service-331','account-33',true,true,'["33-group-one-resource-id"]','test-1.com','test-332.com'); diff --git a/integration_tests/management/network_map_db/network_map_data_golden.json b/integration_tests/management/network_map_db/network_map_data_golden.json index e78982850..2214456ec 100644 --- a/integration_tests/management/network_map_db/network_map_data_golden.json +++ b/integration_tests/management/network_map_db/network_map_data_golden.json @@ -1,8 +1,8 @@ { "Peers": { - "peer-id-1": { - "ID": "peer-id-1", - "Key": "key-1", + "peer-id-331": { + "ID": "peer-id-331", + "Key": "key-331", "SSHKey": "ssh-key-1", "DNSLabel": "peer-1", "UserID": "user-id-1", @@ -53,9 +53,9 @@ "ConnectionIP": "46.201.148.187" } }, - "peer-id-2": { - "ID": "peer-id-2", - "Key": "key-2", + "peer-id-332": { + "ID": "peer-id-332", + "Key": "key-332", "SSHKey": "ssh-key-2", "DNSLabel": "peer-2", "UserID": "user-id-2", @@ -106,9 +106,9 @@ "ConnectionIP": "46.201.149.187" } }, - "peer-id-3": { - "ID": "peer-id-3", - "Key": "key-3", + "peer-id-333": { + "ID": "peer-id-333", + "Key": "key-333", "SSHKey": "ssh-key-3", "DNSLabel": "peer-3", "UserID": "user-id-3", @@ -161,19 +161,19 @@ } }, "Groups": { - "group-no-resources-id": { - "ID": "group-no-resources-id", + "33-group-no-resources-id": { + "ID": "33-group-no-resources-id", "Name": "group-3-name", - "PublicID": "group-no-resources-id-public", + "PublicID": "33-group-no-resources-id-public", "Peers": null, "Resources": null }, - "group-one-resource-id": { - "ID": "group-one-resource-id", + "33-group-one-resource-id": { + "ID": "33-group-one-resource-id", "Name": "group-1-name", "PublicID": "group-one-resource-id-public", "Peers": [ - "peer-id-1" + "peer-id-331" ], "Resources": [ { @@ -182,13 +182,13 @@ } ] }, - "group-two-resources-id": { - "ID": "group-two-resources-id", + "33-group-two-resources-id": { + "ID": "33-group-two-resources-id", "Name": "group-2-name", - "PublicID": "group-two-resources-id-public", + "PublicID": "33-group-two-resources-id-public", "Peers": [ - "peer-id-2", - "peer-id-3" + "peer-id-332", + "peer-id-333" ], "Resources": [ { @@ -202,11 +202,93 @@ ] } }, - "Policies": [], - "Routes": [], + "Policies": [ + { + "ID": "policy-331", + "PublicID": "policy-1-public", + "Enabled": true, + "SourcePostureChecks": [ + "posture-checks-1", + "posture-checks-2" + ], + "Rules": [ + { + "ID": "policy-331", + "PolicyID": "policy-331", + "Enabled": true, + "Action": "accept", + "Protocol": "tcp", + "Bidirectional": true, + "Sources": [ + "33-group-one-resource-id", + "33-group-two-resources-id" + ], + "Destinations": [ + "33-group-one-resource-id", + "33-group-two-resources-id" + ], + "SourceResource": { + "ID": "host-id-1", + "Type": "host" + }, + "DestinationResource": { + "ID": "domain-331", + "Type": "domain" + }, + "Ports": [ + "8080", + "8443" + ], + "PortRanges": [ + { + "Start": 8080, + "End": 8090 + } + ], + "AuthorizedGroups": { + "33-group-one-resource-id": [ + "user-1", + "user-2" + ] + }, + "AuthorizedUser": "user-3" + } + ] + } + ], + "Routes": [ + { + "ID": "route-331", + "AccountID": "account-33", + "PublicID": "route-1-public", + "Network": "172.0.0.0/16", + "Domains": [ + "test-1.com" + ], + "KeepRoute": true, + "NetID": "route-331-net-id", + "Description": "route-1", + "Peer": "peer-id-331", + "PeerID": "peer-id-331", + "PeerGroups": [ + "33-group-one-resource-id" + ], + "NetworkType": 1, + "Masquerade": true, + "Metric": 9999, + "Enabled": true, + "Groups": [ + "33-group-one-resource-id" + ], + "AccessControlGroups": [ + "33-group-one-resource-id" + ], + "SkipAutoApply": false + } + ], "NameServerGroups": [ { - "ID": "nsgroup-1", + "ID": "nsgroup-331", "PublicID": "nsgroup-1-public", "Name": "nsgroup-1", "Description": "nsgroup-1", @@ -218,7 +300,7 @@ } ], "Groups": [ - "group-one-resource-id" + "33-group-one-resource-id" ], "Primary": true, "Domains": [ @@ -228,7 +310,7 @@ "SearchDomainsEnabled": false }, { - "ID": "nsgroup-2", + "ID": "nsgroup-332", "PublicID": "nsgroup-2-public", "Name": "nsgroup-2", "Description": "nsgroup-2", @@ -240,8 +322,8 @@ } ], "Groups": [ - "group-one-resource-id", - "group-no-resources-id" + "33-group-one-resource-id", + "33-group-no-resources-id" ], "Primary": true, "Domains": [ @@ -250,23 +332,38 @@ ], "Enabled": true, "SearchDomainsEnabled": false - }, - { - "ID": "nsgroup-3", - "PublicID": "nsgroup-3-public", - "Name": "", - "Description": "", - "NameServers": null, - "Groups": null, - "Primary": false, - "Domains": null, - "Enabled": true, - "SearchDomainsEnabled": false } ], - "NetworkResources": [], + "NetworkResources": [ + { + "ID": "net-resource-331", + "NetworkID": "network-331", + "AccountID": "account-33", + "PublicID": "net-resource-public-1", + "Name": "network-resource-1", + "Description": "network-resource-1", + "Type": "subnet", + "Address": "", + "Domain": "", + "Prefix": "10.0.0.0/16", + "Enabled": true + }, + { + "ID": "net-resource-332", + "NetworkID": "network-332", + "AccountID": "account-33", + "PublicID": "net-resource-public-2", + "Name": "network-resource-2", + "Description": "network-resource-2", + "Type": "domain", + "Address": "", + "Domain": "test.com", + "Prefix": "", + "Enabled": true + } + ], "Network": { - "Identifier": "network-1", + "Identifier": "network-331", "Net": { "IP": "100.103.0.0", "Mask": "//8AAA==" @@ -291,7 +388,7 @@ "PeerInactivityExpiration": 86400000000000, "DNSDomain": "", "IPv6EnabledGroups": [ - "group-one-resource-id" + "33-group-one-resource-id" ], "RoutingPeerDNSResolutionEnabled": false, "LazyConnectionEnabled": false, @@ -299,73 +396,120 @@ "AutoUpdateAlways": false, "MetricsPushEnabled": false }, - "PostureChecks": {}, + "PostureChecks": { + "posturecheck-331": { + "ID": "posturecheck-331", + "Checks": { + "NBVersionCheck": { + "MinVersion": "0.25.0" + }, + "OSVersionCheck": { + "Android": null, + "Darwin": { + "MinVersion": "12.0" + }, + "Ios": null, + "Linux": null, + "Windows": null + }, + "GeoLocationCheck": { + "Locations": [ + { + "CountryCode": "FI", + "CityName": "" + } + ], + "Action": "allow" + }, + "PeerNetworkRangeCheck": { + "Action": "deny", + "Ranges": [ + "192.168.0.1/24" + ] + }, + "ProcessCheck": null + } + } + }, "PostureValidation": null, "AllowedUserIDs": {}, - "NetworkXIDToPublicID": {}, - "PostureCheckXIDToPublicID": {}, + "NetworkXIDToPublicID": { + "network-331": "network-1-public", + "network-332": "network-2-public" + }, + "PostureCheckXIDToPublicID": { + "posturecheck-331": "posturecheck-1-public" + }, "ValidatedPeers": { "peer-id-1": {}, "peer-id-2": {}, "peer-id-3": {} }, "ResourcePolicies": {}, - "Routers": {}, + "Routers": { + "network-id-1": { + "peer-id-331": { + "PublicID": "public-id-1", + "PeerGroups": [ + "33-group-one-resource-id" + ], + "Masquerade": true, + "Metric": 999, + "Enabled": true + } + }, + "network-id-2": { + "peer-id-332": { + "PublicID": "public-id-2", + "PeerGroups": [ + "33-group-two-resources-id", + "33-group-no-resources-id" + ], + "Masquerade": true, + "Metric": 333, + "Enabled": true + }, + "peer-id-333": { + "PublicID": "public-id-2", + "PeerGroups": [ + "33-group-two-resources-id", + "33-group-no-resources-id" + ], + "Masquerade": true, + "Metric": 333, + "Enabled": true + } + } + }, "GroupIDToUserIDs": {}, "DNSDomain": "", "ProxyTargetedDomainResourceIDs": {}, "AppliedZoneCandidates": [ { "DistributionGroups": [ - "group-one-resource-id" + "33-group-one-resource-id" ], "Zone": { - "Domain": "test-1.com", + "Domain": "test-331.com", "Records": [ { - "Name": "test.test-1.com", + "Name": "test.test-331.com", "Type": 1, "Class": "IN", "TTL": 1800, "RData": "1.1.1.1" }, { - "Name": "test2.test-1.com", + "Name": "test2.test-331.com", "Type": 1, "Class": "IN", "TTL": 1800, "RData": "1.1.1.2" - }, - { - "Name": "test3.test-1.com", - "Type": 5, - "Class": "IN", - "TTL": 1800, - "RData": "test4.test-1.com." } ], "SearchDomainDisabled": false, "NonAuthoritative": false } - }, - { - "DistributionGroups": [ - "group-two-resources-id" - ], - "Zone": { - "Domain": "test-2.com", - "Records": [ - { - "Name": "test2.test-2.com", - "Type": 5, - "Class": "IN", - "TTL": 1800, - "RData": "test3.test-2.com." - } - ], - "SearchDomainDisabled": true, - "NonAuthoritative": false - } } ], "PrivateServiceCandidates": null diff --git a/integration_tests/management/network_map_db/network_map_data_test.go b/integration_tests/management/network_map_db/network_map_data_test.go index 1d3ff2ace..25c0c0e77 100644 --- a/integration_tests/management/network_map_db/network_map_data_test.go +++ b/integration_tests/management/network_map_db/network_map_data_test.go @@ -9,6 +9,7 @@ import ( "os" "path/filepath" "runtime" + "strings" "testing" "github.com/golang/mock/gomock" @@ -16,9 +17,13 @@ import ( "github.com/netbirdio/netbird/management/server/integrations/integrated_validator" "github.com/netbirdio/netbird/management/server/settings" "github.com/netbirdio/netbird/management/server/types" + log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" ) +//go:embed network_map_data.sql +var nmapData string + //go:embed network_map_data_golden.json var goldenNMap string @@ -45,7 +50,13 @@ func TestGetNetworkMapData(t *testing.T) { IntegratedPeerValidator: peerValidators, } - nmap, err := storeImpl.GetNetworkMapData(ctx, "account-1") + for _, query := range strings.Split(nmapData, ";") { + if err := store(t).Exec(ctx, query); err != nil { + log.Fatalf("error initializing nmap test: %s", err.Error()) + } + } + + nmap, err := storeImpl.GetNetworkMapData(ctx, "account-33") assert.NoError(t, err) serializedNMap, err := json.MarshalIndent(nmap, "", " ") diff --git a/management/internals/network_map_db/pgsql/pg_store.go b/management/internals/network_map_db/pgsql/pg_store.go index 737424ab2..0cae610f8 100644 --- a/management/internals/network_map_db/pgsql/pg_store.go +++ b/management/internals/network_map_db/pgsql/pg_store.go @@ -67,6 +67,11 @@ func (p *PgStore) UsingConnection(c *pgx.Conn) networkmapdb.NetworkMapDBStoreCon return &PgStoreConn{Conn: c} } +func (p *PgStore) Exec(ctx context.Context, query string, args ...any) error { + _, err := p.Pool.Exec(ctx, query, args...) + return err +} + func (p *PgStore) BeginTx(ctx context.Context) (networkmapdb.NetworkMapDBStoreConn, error) { tx, err := p.Pool.BeginTx(ctx, pgx.TxOptions{IsoLevel: pgx.RepeatableRead, AccessMode: pgx.ReadOnly}) if err != nil { diff --git a/management/internals/network_map_db/shared_types.go b/management/internals/network_map_db/shared_types.go index fd3f11e08..1653289e8 100644 --- a/management/internals/network_map_db/shared_types.go +++ b/management/internals/network_map_db/shared_types.go @@ -19,6 +19,7 @@ var ErrDnsUnsupportedRecordType = errors.New("unsupported record type") type NetworkMapDBStore interface { //nolint:revive // established name across the codebase BeginTx(ctx context.Context) (NetworkMapDBStoreConn, error) + Exec(ctx context.Context, query string, args ...any) error } type NetworkMapDBStoreConn interface { //nolint:revive // established name across the codebase diff --git a/management/internals/network_map_db/sqlite/sqlite_store.go b/management/internals/network_map_db/sqlite/sqlite_store.go index 7632b065d..14abf80bc 100644 --- a/management/internals/network_map_db/sqlite/sqlite_store.go +++ b/management/internals/network_map_db/sqlite/sqlite_store.go @@ -84,6 +84,11 @@ func (s *SqliteStore) BeginTx(ctx context.Context) (networkmapdb.NetworkMapDBSto return &SqliteStoreConn{Conn: tx}, nil } +func (s *SqliteStore) Exec(_ context.Context, query string, args ...any) error { + _, err := s.Db.Exec(query, args...) + return err +} + func (sc *SqliteStoreConn) RollbackTx(ctx context.Context) error { tx, ok := sc.Conn.(*sql.Tx) if !ok {