mirror of
https://github.com/netbirdio/netbird.git
synced 2026-05-15 13:19:56 +00:00
[management, client] Add IPv6 overlay support (#5631)
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
@@ -1503,7 +1504,7 @@ func (s *SqlStore) getAccount(ctx context.Context, accountID string) (*types.Acc
|
||||
SELECT
|
||||
id, created_by, created_at, domain, domain_category, is_domain_primary_account,
|
||||
-- Embedded Network
|
||||
network_identifier, network_net, network_dns, network_serial,
|
||||
network_identifier, network_net, network_net_v6, network_dns, network_serial,
|
||||
-- Embedded DNSSettings
|
||||
dns_settings_disabled_management_groups,
|
||||
-- Embedded Settings
|
||||
@@ -1512,7 +1513,7 @@ func (s *SqlStore) getAccount(ctx context.Context, accountID string) (*types.Acc
|
||||
settings_regular_users_view_blocked, settings_groups_propagation_enabled,
|
||||
settings_jwt_groups_enabled, settings_jwt_groups_claim_name, settings_jwt_allow_groups,
|
||||
settings_routing_peer_dns_resolution_enabled, settings_dns_domain, settings_network_range,
|
||||
settings_lazy_connection_enabled,
|
||||
settings_network_range_v6, settings_ipv6_enabled_groups, settings_lazy_connection_enabled,
|
||||
-- Embedded ExtraSettings
|
||||
settings_extra_peer_approval_enabled, settings_extra_user_approval_required,
|
||||
settings_extra_integrated_validator, settings_extra_integrated_validator_groups
|
||||
@@ -1531,12 +1532,15 @@ func (s *SqlStore) getAccount(ctx context.Context, accountID string) (*types.Acc
|
||||
sRoutingPeerDNSResolutionEnabled sql.NullBool
|
||||
sDNSDomain sql.NullString
|
||||
sNetworkRange sql.NullString
|
||||
sNetworkRangeV6 sql.NullString
|
||||
sIPv6EnabledGroups sql.NullString
|
||||
sLazyConnectionEnabled sql.NullBool
|
||||
sExtraPeerApprovalEnabled sql.NullBool
|
||||
sExtraUserApprovalRequired sql.NullBool
|
||||
sExtraIntegratedValidator sql.NullString
|
||||
sExtraIntegratedValidatorGroups sql.NullString
|
||||
networkNet sql.NullString
|
||||
networkNetV6 sql.NullString
|
||||
dnsSettingsDisabledGroups sql.NullString
|
||||
networkIdentifier sql.NullString
|
||||
networkDns sql.NullString
|
||||
@@ -1545,14 +1549,14 @@ func (s *SqlStore) getAccount(ctx context.Context, accountID string) (*types.Acc
|
||||
)
|
||||
err := s.pool.QueryRow(ctx, accountQuery, accountID).Scan(
|
||||
&account.Id, &account.CreatedBy, &createdAt, &account.Domain, &account.DomainCategory, &account.IsDomainPrimaryAccount,
|
||||
&networkIdentifier, &networkNet, &networkDns, &networkSerial,
|
||||
&networkIdentifier, &networkNet, &networkNetV6, &networkDns, &networkSerial,
|
||||
&dnsSettingsDisabledGroups,
|
||||
&sPeerLoginExpirationEnabled, &sPeerLoginExpiration,
|
||||
&sPeerInactivityExpirationEnabled, &sPeerInactivityExpiration,
|
||||
&sRegularUsersViewBlocked, &sGroupsPropagationEnabled,
|
||||
&sJWTGroupsEnabled, &sJWTGroupsClaimName, &sJWTAllowGroups,
|
||||
&sRoutingPeerDNSResolutionEnabled, &sDNSDomain, &sNetworkRange,
|
||||
&sLazyConnectionEnabled,
|
||||
&sNetworkRangeV6, &sIPv6EnabledGroups, &sLazyConnectionEnabled,
|
||||
&sExtraPeerApprovalEnabled, &sExtraUserApprovalRequired,
|
||||
&sExtraIntegratedValidator, &sExtraIntegratedValidatorGroups,
|
||||
)
|
||||
@@ -1621,6 +1625,15 @@ func (s *SqlStore) getAccount(ctx context.Context, accountID string) (*types.Acc
|
||||
if sNetworkRange.Valid {
|
||||
_ = json.Unmarshal([]byte(sNetworkRange.String), &account.Settings.NetworkRange)
|
||||
}
|
||||
if networkNetV6.Valid {
|
||||
_ = json.Unmarshal([]byte(networkNetV6.String), &account.Network.NetV6)
|
||||
}
|
||||
if sNetworkRangeV6.Valid {
|
||||
_ = json.Unmarshal([]byte(sNetworkRangeV6.String), &account.Settings.NetworkRangeV6)
|
||||
}
|
||||
if sIPv6EnabledGroups.Valid {
|
||||
_ = json.Unmarshal([]byte(sIPv6EnabledGroups.String), &account.Settings.IPv6EnabledGroups)
|
||||
}
|
||||
|
||||
if sExtraPeerApprovalEnabled.Valid {
|
||||
account.Settings.Extra.PeerApprovalEnabled = sExtraPeerApprovalEnabled.Bool
|
||||
@@ -1702,12 +1715,12 @@ func (s *SqlStore) getSetupKeys(ctx context.Context, accountID string) ([]types.
|
||||
|
||||
func (s *SqlStore) getPeers(ctx context.Context, accountID string) ([]nbpeer.Peer, error) {
|
||||
const query = `SELECT id, account_id, key, ip, name, dns_label, user_id, ssh_key, ssh_enabled, login_expiration_enabled,
|
||||
inactivity_expiration_enabled, last_login, created_at, ephemeral, extra_dns_labels, allow_extra_dns_labels, meta_hostname,
|
||||
meta_go_os, meta_kernel, meta_core, meta_platform, meta_os, meta_os_version, meta_wt_version, meta_ui_version,
|
||||
inactivity_expiration_enabled, last_login, created_at, ephemeral, extra_dns_labels, allow_extra_dns_labels, meta_hostname,
|
||||
meta_go_os, meta_kernel, meta_core, meta_platform, meta_os, meta_os_version, meta_wt_version, meta_ui_version,
|
||||
meta_kernel_version, meta_network_addresses, meta_system_serial_number, meta_system_product_name, meta_system_manufacturer,
|
||||
meta_environment, meta_flags, meta_files, peer_status_last_seen, peer_status_connected, peer_status_login_expired,
|
||||
peer_status_requires_approval, location_connection_ip, location_country_code, location_city_name,
|
||||
location_geo_name_id, proxy_meta_embedded, proxy_meta_cluster FROM peers WHERE account_id = $1`
|
||||
meta_environment, meta_flags, meta_files, meta_capabilities, peer_status_last_seen, peer_status_connected, peer_status_login_expired,
|
||||
peer_status_requires_approval, location_connection_ip, location_country_code, location_city_name,
|
||||
location_geo_name_id, proxy_meta_embedded, proxy_meta_cluster, ipv6 FROM peers WHERE account_id = $1`
|
||||
rows, err := s.pool.Query(ctx, query, accountID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1721,7 +1734,7 @@ func (s *SqlStore) getPeers(ctx context.Context, accountID string) ([]nbpeer.Pee
|
||||
sshEnabled, loginExpirationEnabled, inactivityExpirationEnabled, ephemeral, allowExtraDNSLabels sql.NullBool
|
||||
peerStatusLastSeen sql.NullTime
|
||||
peerStatusConnected, peerStatusLoginExpired, peerStatusRequiresApproval, proxyEmbedded sql.NullBool
|
||||
ip, extraDNS, netAddr, env, flags, files, connIP []byte
|
||||
ip, extraDNS, netAddr, env, flags, files, capabilities, connIP, ipv6 []byte
|
||||
metaHostname, metaGoOS, metaKernel, metaCore, metaPlatform sql.NullString
|
||||
metaOS, metaOSVersion, metaWtVersion, metaUIVersion, metaKernelVersion sql.NullString
|
||||
metaSystemSerialNumber, metaSystemProductName, metaSystemManufacturer sql.NullString
|
||||
@@ -1733,9 +1746,9 @@ func (s *SqlStore) getPeers(ctx context.Context, accountID string) ([]nbpeer.Pee
|
||||
&loginExpirationEnabled, &inactivityExpirationEnabled, &lastLogin, &createdAt, &ephemeral, &extraDNS,
|
||||
&allowExtraDNSLabels, &metaHostname, &metaGoOS, &metaKernel, &metaCore, &metaPlatform,
|
||||
&metaOS, &metaOSVersion, &metaWtVersion, &metaUIVersion, &metaKernelVersion, &netAddr,
|
||||
&metaSystemSerialNumber, &metaSystemProductName, &metaSystemManufacturer, &env, &flags, &files,
|
||||
&metaSystemSerialNumber, &metaSystemProductName, &metaSystemManufacturer, &env, &flags, &files, &capabilities,
|
||||
&peerStatusLastSeen, &peerStatusConnected, &peerStatusLoginExpired, &peerStatusRequiresApproval, &connIP,
|
||||
&locationCountryCode, &locationCityName, &locationGeoNameID, &proxyEmbedded, &proxyCluster)
|
||||
&locationCountryCode, &locationCityName, &locationGeoNameID, &proxyEmbedded, &proxyCluster, &ipv6)
|
||||
|
||||
if err == nil {
|
||||
if lastLogin.Valid {
|
||||
@@ -1828,6 +1841,9 @@ func (s *SqlStore) getPeers(ctx context.Context, accountID string) ([]nbpeer.Pee
|
||||
if ip != nil {
|
||||
_ = json.Unmarshal(ip, &p.IP)
|
||||
}
|
||||
if ipv6 != nil {
|
||||
_ = json.Unmarshal(ipv6, &p.IPv6)
|
||||
}
|
||||
if extraDNS != nil {
|
||||
_ = json.Unmarshal(extraDNS, &p.ExtraDNSLabels)
|
||||
}
|
||||
@@ -1843,6 +1859,9 @@ func (s *SqlStore) getPeers(ctx context.Context, accountID string) ([]nbpeer.Pee
|
||||
if files != nil {
|
||||
_ = json.Unmarshal(files, &p.Meta.Files)
|
||||
}
|
||||
if capabilities != nil {
|
||||
_ = json.Unmarshal(capabilities, &p.Meta.Capabilities)
|
||||
}
|
||||
if connIP != nil {
|
||||
_ = json.Unmarshal(connIP, &p.Location.ConnectionIP)
|
||||
}
|
||||
@@ -2586,7 +2605,7 @@ func (s *SqlStore) GetAccountIDBySetupKey(ctx context.Context, setupKey string)
|
||||
return accountID, nil
|
||||
}
|
||||
|
||||
func (s *SqlStore) GetTakenIPs(ctx context.Context, lockStrength LockingStrength, accountID string) ([]net.IP, error) {
|
||||
func (s *SqlStore) GetTakenIPs(ctx context.Context, lockStrength LockingStrength, accountID string) ([]netip.Addr, error) {
|
||||
tx := s.db
|
||||
if lockStrength != LockingStrengthNone {
|
||||
tx = tx.Clauses(clause.Locking{Strength: string(lockStrength)})
|
||||
@@ -2594,7 +2613,6 @@ func (s *SqlStore) GetTakenIPs(ctx context.Context, lockStrength LockingStrength
|
||||
|
||||
var ipJSONStrings []string
|
||||
|
||||
// Fetch the IP addresses as JSON strings
|
||||
result := tx.Model(&nbpeer.Peer{}).
|
||||
Where("account_id = ?", accountID).
|
||||
Pluck("ip", &ipJSONStrings)
|
||||
@@ -2605,14 +2623,13 @@ func (s *SqlStore) GetTakenIPs(ctx context.Context, lockStrength LockingStrength
|
||||
return nil, status.Errorf(status.Internal, "issue getting IPs from store: %s", result.Error)
|
||||
}
|
||||
|
||||
// Convert the JSON strings to net.IP objects
|
||||
ips := make([]net.IP, len(ipJSONStrings))
|
||||
ips := make([]netip.Addr, len(ipJSONStrings))
|
||||
for i, ipJSON := range ipJSONStrings {
|
||||
var ip net.IP
|
||||
var ip netip.Addr
|
||||
if err := json.Unmarshal([]byte(ipJSON), &ip); err != nil {
|
||||
return nil, status.Errorf(status.Internal, "issue parsing IP JSON from store")
|
||||
}
|
||||
ips[i] = ip
|
||||
ips[i] = ip.Unmap()
|
||||
}
|
||||
|
||||
return ips, nil
|
||||
@@ -3214,7 +3231,7 @@ func (s *SqlStore) GetAccountPeers(ctx context.Context, lockStrength LockingStre
|
||||
query = query.Where("name LIKE ?", "%"+nameFilter+"%")
|
||||
}
|
||||
if ipFilter != "" {
|
||||
query = query.Where("ip LIKE ?", "%"+ipFilter+"%")
|
||||
query = query.Where("ip LIKE ? OR ipv6 LIKE ?", "%"+ipFilter+"%", "%"+ipFilter+"%")
|
||||
}
|
||||
|
||||
if err := query.Find(&peers).Error; err != nil {
|
||||
@@ -4090,9 +4107,10 @@ func (s *SqlStore) SaveAccountSettings(ctx context.Context, accountID string, se
|
||||
return status.Errorf(status.Internal, "failed to save account settings to store")
|
||||
}
|
||||
|
||||
if result.RowsAffected == 0 {
|
||||
return status.NewAccountNotFoundError(accountID)
|
||||
}
|
||||
// MySQL reports RowsAffected=0 for no-op updates where values don't change,
|
||||
// unlike SQLite/Postgres which report matched rows. Skip the check since the
|
||||
// caller (UpdateAccountSettings) already verified the account exists via
|
||||
// GetAccountSettings with LockingStrengthUpdate.
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -4517,11 +4535,15 @@ func (s *SqlStore) GetPeerByIP(ctx context.Context, lockStrength LockingStrength
|
||||
tx = tx.Clauses(clause.Locking{Strength: string(lockStrength)})
|
||||
}
|
||||
|
||||
column := "ip"
|
||||
if ip.To4() == nil {
|
||||
column = "ipv6"
|
||||
}
|
||||
jsonValue := fmt.Sprintf(`"%s"`, ip.String())
|
||||
|
||||
var peer nbpeer.Peer
|
||||
result := tx.
|
||||
Take(&peer, "account_id = ? AND ip = ?", accountID, jsonValue)
|
||||
Take(&peer, fmt.Sprintf("account_id = ? AND %s = ?", column), accountID, jsonValue)
|
||||
if result.Error != nil {
|
||||
// no logging here
|
||||
return nil, status.Errorf(status.Internal, "failed to get peer from store")
|
||||
@@ -4643,6 +4665,27 @@ func (s *SqlStore) UpdateAccountNetwork(ctx context.Context, accountID string, i
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateAccountNetworkV6 updates the IPv6 network range for the account.
|
||||
func (s *SqlStore) UpdateAccountNetworkV6(ctx context.Context, accountID string, ipNet net.IPNet) error {
|
||||
patch := accountNetworkPatch{
|
||||
Network: &types.Network{NetV6: ipNet},
|
||||
}
|
||||
|
||||
result := s.db.
|
||||
Model(&types.Account{}).
|
||||
Where(idQueryCondition, accountID).
|
||||
Updates(&patch)
|
||||
|
||||
if result.Error != nil {
|
||||
log.WithContext(ctx).Errorf("failed to update account network v6: %v", result.Error)
|
||||
return status.Errorf(status.Internal, "update account network v6")
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return status.NewAccountNotFoundError(accountID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SqlStore) GetPeersByGroupIDs(ctx context.Context, accountID string, groupIDs []string) ([]*nbpeer.Peer, error) {
|
||||
if len(groupIDs) == 0 {
|
||||
return []*nbpeer.Peer{}, nil
|
||||
|
||||
@@ -148,7 +148,8 @@ func TestGetAccount_ComprehensiveFieldValidation(t *testing.T) {
|
||||
AccountID: accountID,
|
||||
Key: "peer-key-1-AAAA",
|
||||
Name: "Peer 1",
|
||||
IP: net.ParseIP("100.64.0.1"),
|
||||
IP: netip.MustParseAddr("100.64.0.1"),
|
||||
IPv6: netip.MustParseAddr("fd00::1"),
|
||||
Meta: nbpeer.PeerSystemMeta{
|
||||
Hostname: "peer1.example.com",
|
||||
GoOS: "linux",
|
||||
@@ -195,7 +196,8 @@ func TestGetAccount_ComprehensiveFieldValidation(t *testing.T) {
|
||||
AccountID: accountID,
|
||||
Key: "peer-key-2-BBBB",
|
||||
Name: "Peer 2",
|
||||
IP: net.ParseIP("100.64.0.2"),
|
||||
IP: netip.MustParseAddr("100.64.0.2"),
|
||||
IPv6: netip.MustParseAddr("fd00::2"),
|
||||
Meta: nbpeer.PeerSystemMeta{
|
||||
Hostname: "peer2.example.com",
|
||||
GoOS: "darwin",
|
||||
@@ -232,7 +234,8 @@ func TestGetAccount_ComprehensiveFieldValidation(t *testing.T) {
|
||||
AccountID: accountID,
|
||||
Key: "peer-key-3-CCCC",
|
||||
Name: "Peer 3 (Ephemeral)",
|
||||
IP: net.ParseIP("100.64.0.3"),
|
||||
IP: netip.MustParseAddr("100.64.0.3"),
|
||||
IPv6: netip.MustParseAddr("fd00::3"),
|
||||
Meta: nbpeer.PeerSystemMeta{
|
||||
Hostname: "peer3.example.com",
|
||||
GoOS: "windows",
|
||||
@@ -710,7 +713,7 @@ func TestGetAccount_ComprehensiveFieldValidation(t *testing.T) {
|
||||
require.True(t, exists, "Peer 1 should exist")
|
||||
assert.Equal(t, "Peer 1", p1.Name, "Peer 1 name mismatch")
|
||||
assert.Equal(t, "peer-key-1-AAAA", p1.Key, "Peer 1 key mismatch")
|
||||
assert.True(t, p1.IP.Equal(net.ParseIP("100.64.0.1")), "Peer 1 IP mismatch")
|
||||
assert.Equal(t, netip.MustParseAddr("100.64.0.1"), p1.IP, "Peer 1 IP mismatch")
|
||||
assert.Equal(t, userID1, p1.UserID, "Peer 1 user ID mismatch")
|
||||
assert.True(t, p1.SSHEnabled, "Peer 1 SSH should be enabled")
|
||||
assert.Equal(t, "ssh-rsa AAAAB3NzaC1...", p1.SSHKey, "Peer 1 SSH key mismatch")
|
||||
|
||||
@@ -94,11 +94,12 @@ func runLargeTest(t *testing.T, store Store) {
|
||||
for n := 0; n < numPerAccount; n++ {
|
||||
netIP := randomIPv4()
|
||||
peerID := fmt.Sprintf("%s-peer-%d", account.Id, n)
|
||||
addr, _ := netip.AddrFromSlice(netIP)
|
||||
|
||||
peer := &nbpeer.Peer{
|
||||
ID: peerID,
|
||||
Key: peerID,
|
||||
IP: netIP,
|
||||
IP: addr.Unmap(),
|
||||
Name: peerID,
|
||||
DNSLabel: peerID,
|
||||
UserID: "testuser",
|
||||
@@ -235,7 +236,8 @@ func Test_SaveAccount(t *testing.T) {
|
||||
account.SetupKeys[setupKey.Key] = setupKey
|
||||
account.Peers["testpeer"] = &nbpeer.Peer{
|
||||
Key: "peerkey",
|
||||
IP: net.IP{127, 0, 0, 1},
|
||||
IP: netip.AddrFrom4([4]byte{127, 0, 0, 1}),
|
||||
IPv6: netip.MustParseAddr("fd00::1"),
|
||||
Meta: nbpeer.PeerSystemMeta{},
|
||||
Name: "peer name",
|
||||
Status: &nbpeer.PeerStatus{Connected: true, LastSeen: time.Now().UTC()},
|
||||
@@ -249,7 +251,8 @@ func Test_SaveAccount(t *testing.T) {
|
||||
account2.SetupKeys[setupKey.Key] = setupKey
|
||||
account2.Peers["testpeer2"] = &nbpeer.Peer{
|
||||
Key: "peerkey2",
|
||||
IP: net.IP{127, 0, 0, 2},
|
||||
IP: netip.AddrFrom4([4]byte{127, 0, 0, 2}),
|
||||
IPv6: netip.MustParseAddr("fd00::2"),
|
||||
Meta: nbpeer.PeerSystemMeta{},
|
||||
Name: "peer name 2",
|
||||
Status: &nbpeer.PeerStatus{Connected: true, LastSeen: time.Now().UTC()},
|
||||
@@ -316,7 +319,8 @@ func TestSqlite_DeleteAccount(t *testing.T) {
|
||||
account.SetupKeys[setupKey.Key] = setupKey
|
||||
account.Peers["testpeer"] = &nbpeer.Peer{
|
||||
Key: "peerkey",
|
||||
IP: net.IP{127, 0, 0, 1},
|
||||
IP: netip.AddrFrom4([4]byte{127, 0, 0, 1}),
|
||||
IPv6: netip.MustParseAddr("fd00::1"),
|
||||
Meta: nbpeer.PeerSystemMeta{},
|
||||
Name: "peer name",
|
||||
Status: &nbpeer.PeerStatus{Connected: true, LastSeen: time.Now().UTC()},
|
||||
@@ -499,7 +503,8 @@ func TestSqlStore_SavePeer(t *testing.T) {
|
||||
peer := &nbpeer.Peer{
|
||||
Key: "peerkey",
|
||||
ID: "testpeer",
|
||||
IP: net.IP{127, 0, 0, 1},
|
||||
IP: netip.AddrFrom4([4]byte{127, 0, 0, 1}),
|
||||
IPv6: netip.MustParseAddr("fd00::1"),
|
||||
Meta: nbpeer.PeerSystemMeta{Hostname: "testingpeer"},
|
||||
Name: "peer name",
|
||||
Status: &nbpeer.PeerStatus{Connected: true, LastSeen: time.Now().UTC()},
|
||||
@@ -556,7 +561,8 @@ func TestSqlStore_SavePeerStatus(t *testing.T) {
|
||||
account.Peers["testpeer"] = &nbpeer.Peer{
|
||||
Key: "peerkey",
|
||||
ID: "testpeer",
|
||||
IP: net.IP{127, 0, 0, 1},
|
||||
IP: netip.AddrFrom4([4]byte{127, 0, 0, 1}),
|
||||
IPv6: netip.MustParseAddr("fd00::1"),
|
||||
Meta: nbpeer.PeerSystemMeta{},
|
||||
Name: "peer name",
|
||||
Status: &nbpeer.PeerStatus{Connected: true, LastSeen: time.Now().UTC()},
|
||||
@@ -784,7 +790,8 @@ func newAccount(store Store, id int) error {
|
||||
account.SetupKeys[setupKey.Key] = setupKey
|
||||
account.Peers["p"+str] = &nbpeer.Peer{
|
||||
Key: "peerkey" + str,
|
||||
IP: net.IP{127, 0, 0, 1},
|
||||
IP: netip.AddrFrom4([4]byte{127, 0, 0, 1}),
|
||||
IPv6: netip.MustParseAddr("fd00::1"),
|
||||
Meta: nbpeer.PeerSystemMeta{},
|
||||
Name: "peer name",
|
||||
Status: &nbpeer.PeerStatus{Connected: true, LastSeen: time.Now().UTC()},
|
||||
@@ -823,7 +830,8 @@ func TestPostgresql_SaveAccount(t *testing.T) {
|
||||
account.SetupKeys[setupKey.Key] = setupKey
|
||||
account.Peers["testpeer"] = &nbpeer.Peer{
|
||||
Key: "peerkey",
|
||||
IP: net.IP{127, 0, 0, 1},
|
||||
IP: netip.AddrFrom4([4]byte{127, 0, 0, 1}),
|
||||
IPv6: netip.MustParseAddr("fd00::1"),
|
||||
Meta: nbpeer.PeerSystemMeta{},
|
||||
Name: "peer name",
|
||||
Status: &nbpeer.PeerStatus{Connected: true, LastSeen: time.Now().UTC()},
|
||||
@@ -837,7 +845,8 @@ func TestPostgresql_SaveAccount(t *testing.T) {
|
||||
account2.SetupKeys[setupKey.Key] = setupKey
|
||||
account2.Peers["testpeer2"] = &nbpeer.Peer{
|
||||
Key: "peerkey2",
|
||||
IP: net.IP{127, 0, 0, 2},
|
||||
IP: netip.AddrFrom4([4]byte{127, 0, 0, 2}),
|
||||
IPv6: netip.MustParseAddr("fd00::2"),
|
||||
Meta: nbpeer.PeerSystemMeta{},
|
||||
Name: "peer name 2",
|
||||
Status: &nbpeer.PeerStatus{Connected: true, LastSeen: time.Now().UTC()},
|
||||
@@ -903,7 +912,8 @@ func TestPostgresql_DeleteAccount(t *testing.T) {
|
||||
account.SetupKeys[setupKey.Key] = setupKey
|
||||
account.Peers["testpeer"] = &nbpeer.Peer{
|
||||
Key: "peerkey",
|
||||
IP: net.IP{127, 0, 0, 1},
|
||||
IP: netip.AddrFrom4([4]byte{127, 0, 0, 1}),
|
||||
IPv6: netip.MustParseAddr("fd00::1"),
|
||||
Meta: nbpeer.PeerSystemMeta{},
|
||||
Name: "peer name",
|
||||
Status: &nbpeer.PeerStatus{Connected: true, LastSeen: time.Now().UTC()},
|
||||
@@ -1010,37 +1020,39 @@ func TestSqlite_GetTakenIPs(t *testing.T) {
|
||||
|
||||
takenIPs, err := store.GetTakenIPs(context.Background(), LockingStrengthNone, existingAccountID)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []net.IP{}, takenIPs)
|
||||
assert.Equal(t, []netip.Addr{}, takenIPs)
|
||||
|
||||
peer1 := &nbpeer.Peer{
|
||||
ID: "peer1",
|
||||
AccountID: existingAccountID,
|
||||
Key: "key1",
|
||||
DNSLabel: "peer1",
|
||||
IP: net.IP{1, 1, 1, 1},
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
IPv6: netip.MustParseAddr("fd00::1:1:1:1"),
|
||||
}
|
||||
err = store.AddPeerToAccount(context.Background(), peer1)
|
||||
require.NoError(t, err)
|
||||
|
||||
takenIPs, err = store.GetTakenIPs(context.Background(), LockingStrengthNone, existingAccountID)
|
||||
require.NoError(t, err)
|
||||
ip1 := net.IP{1, 1, 1, 1}.To16()
|
||||
assert.Equal(t, []net.IP{ip1}, takenIPs)
|
||||
ip1 := netip.AddrFrom4([4]byte{1, 1, 1, 1})
|
||||
assert.Equal(t, []netip.Addr{ip1}, takenIPs)
|
||||
|
||||
peer2 := &nbpeer.Peer{
|
||||
ID: "peer1second",
|
||||
AccountID: existingAccountID,
|
||||
Key: "key2",
|
||||
DNSLabel: "peer1-1",
|
||||
IP: net.IP{2, 2, 2, 2},
|
||||
IP: netip.AddrFrom4([4]byte{2, 2, 2, 2}),
|
||||
IPv6: netip.MustParseAddr("fd00::2:2:2:2"),
|
||||
}
|
||||
err = store.AddPeerToAccount(context.Background(), peer2)
|
||||
require.NoError(t, err)
|
||||
|
||||
takenIPs, err = store.GetTakenIPs(context.Background(), LockingStrengthNone, existingAccountID)
|
||||
require.NoError(t, err)
|
||||
ip2 := net.IP{2, 2, 2, 2}.To16()
|
||||
assert.Equal(t, []net.IP{ip1, ip2}, takenIPs)
|
||||
ip2 := netip.AddrFrom4([4]byte{2, 2, 2, 2})
|
||||
assert.Equal(t, []netip.Addr{ip1, ip2}, takenIPs)
|
||||
}
|
||||
|
||||
func TestSqlite_GetPeerLabelsInAccount(t *testing.T) {
|
||||
@@ -1060,7 +1072,8 @@ func TestSqlite_GetPeerLabelsInAccount(t *testing.T) {
|
||||
AccountID: existingAccountID,
|
||||
Key: "key1",
|
||||
DNSLabel: "peer1",
|
||||
IP: net.IP{1, 1, 1, 1},
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
IPv6: netip.MustParseAddr("fd00::1:1:1:1"),
|
||||
}
|
||||
err = store.AddPeerToAccount(context.Background(), peer1)
|
||||
require.NoError(t, err)
|
||||
@@ -1074,7 +1087,8 @@ func TestSqlite_GetPeerLabelsInAccount(t *testing.T) {
|
||||
AccountID: existingAccountID,
|
||||
Key: "key2",
|
||||
DNSLabel: "peer1-1",
|
||||
IP: net.IP{2, 2, 2, 2},
|
||||
IP: netip.AddrFrom4([4]byte{2, 2, 2, 2}),
|
||||
IPv6: netip.MustParseAddr("fd00::2:2:2:2"),
|
||||
}
|
||||
err = store.AddPeerToAccount(context.Background(), peer2)
|
||||
require.NoError(t, err)
|
||||
@@ -1127,7 +1141,8 @@ func Test_AddPeerWithSameIP(t *testing.T) {
|
||||
ID: "peer1",
|
||||
AccountID: existingAccountID,
|
||||
Key: "key1",
|
||||
IP: net.IP{1, 1, 1, 1},
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
IPv6: netip.MustParseAddr("fd00::1:1:1:1"),
|
||||
}
|
||||
err = store.AddPeerToAccount(context.Background(), peer1)
|
||||
require.NoError(t, err)
|
||||
@@ -1136,7 +1151,8 @@ func Test_AddPeerWithSameIP(t *testing.T) {
|
||||
ID: "peer1second",
|
||||
AccountID: existingAccountID,
|
||||
Key: "key2",
|
||||
IP: net.IP{1, 1, 1, 1},
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
IPv6: netip.MustParseAddr("fd00::2:2:2:2"),
|
||||
}
|
||||
err = store.AddPeerToAccount(context.Background(), peer2)
|
||||
require.Error(t, err)
|
||||
@@ -2640,7 +2656,8 @@ func TestSqlStore_AddPeerToAccount(t *testing.T) {
|
||||
ID: "peer1",
|
||||
AccountID: accountID,
|
||||
Key: "key",
|
||||
IP: net.IP{1, 1, 1, 1},
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
IPv6: netip.MustParseAddr("fd00::1:1:1:1"),
|
||||
Meta: nbpeer.PeerSystemMeta{
|
||||
Hostname: "hostname",
|
||||
GoOS: "linux",
|
||||
@@ -3815,10 +3832,10 @@ func BenchmarkGetAccountPeers(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func intToIPv4(n uint32) net.IP {
|
||||
ip := make(net.IP, 4)
|
||||
binary.BigEndian.PutUint32(ip, n)
|
||||
return ip
|
||||
func intToIPv4(n uint32) netip.Addr {
|
||||
var b [4]byte
|
||||
binary.BigEndian.PutUint32(b[:], n)
|
||||
return netip.AddrFrom4(b)
|
||||
}
|
||||
|
||||
func TestSqlStore_GetPeersByGroupIDs(t *testing.T) {
|
||||
@@ -3945,7 +3962,8 @@ func TestSqlStore_GetUserIDByPeerKey(t *testing.T) {
|
||||
Key: peerKey,
|
||||
AccountID: existingAccountID,
|
||||
UserID: userID,
|
||||
IP: net.IP{10, 0, 0, 1},
|
||||
IP: netip.AddrFrom4([4]byte{10, 0, 0, 1}),
|
||||
IPv6: netip.MustParseAddr("fd00::a00:1"),
|
||||
DNSLabel: "test-peer-1",
|
||||
}
|
||||
|
||||
@@ -3982,7 +4000,8 @@ func TestSqlStore_GetUserIDByPeerKey_NoUserID(t *testing.T) {
|
||||
Key: peerKey,
|
||||
AccountID: existingAccountID,
|
||||
UserID: "",
|
||||
IP: net.IP{10, 0, 0, 1},
|
||||
IP: netip.AddrFrom4([4]byte{10, 0, 0, 1}),
|
||||
IPv6: netip.MustParseAddr("fd00::a00:1"),
|
||||
DNSLabel: "test-peer-1",
|
||||
}
|
||||
|
||||
@@ -4009,7 +4028,8 @@ func TestSqlStore_ApproveAccountPeers(t *testing.T) {
|
||||
AccountID: accountID,
|
||||
DNSLabel: "peer1.netbird.cloud",
|
||||
Key: "peer1-key",
|
||||
IP: net.ParseIP("100.64.0.1"),
|
||||
IP: netip.MustParseAddr("100.64.0.1"),
|
||||
IPv6: netip.MustParseAddr("fd00::1"),
|
||||
Status: &nbpeer.PeerStatus{
|
||||
RequiresApproval: true,
|
||||
LastSeen: time.Now().UTC(),
|
||||
@@ -4020,7 +4040,8 @@ func TestSqlStore_ApproveAccountPeers(t *testing.T) {
|
||||
AccountID: accountID,
|
||||
DNSLabel: "peer2.netbird.cloud",
|
||||
Key: "peer2-key",
|
||||
IP: net.ParseIP("100.64.0.2"),
|
||||
IP: netip.MustParseAddr("100.64.0.2"),
|
||||
IPv6: netip.MustParseAddr("fd00::2"),
|
||||
Status: &nbpeer.PeerStatus{
|
||||
RequiresApproval: true,
|
||||
LastSeen: time.Now().UTC(),
|
||||
@@ -4031,7 +4052,8 @@ func TestSqlStore_ApproveAccountPeers(t *testing.T) {
|
||||
AccountID: accountID,
|
||||
DNSLabel: "peer3.netbird.cloud",
|
||||
Key: "peer3-key",
|
||||
IP: net.ParseIP("100.64.0.3"),
|
||||
IP: netip.MustParseAddr("100.64.0.3"),
|
||||
IPv6: netip.MustParseAddr("fd00::3"),
|
||||
Status: &nbpeer.PeerStatus{
|
||||
RequiresApproval: false,
|
||||
LastSeen: time.Now().UTC(),
|
||||
|
||||
@@ -344,7 +344,8 @@ func setupBenchmarkDB(b testing.TB) (*SqlStore, func(), string) {
|
||||
ID: fmt.Sprintf("peer-%d", i),
|
||||
AccountID: accountID,
|
||||
Key: fmt.Sprintf("peerkey-%d", i),
|
||||
IP: net.ParseIP(fmt.Sprintf("100.64.0.%d", i+1)),
|
||||
IP: netip.MustParseAddr(fmt.Sprintf("100.64.0.%d", i+1)),
|
||||
IPv6: netip.MustParseAddr(fmt.Sprintf("fd00::%d", i+1)),
|
||||
Name: fmt.Sprintf("peer-name-%d", i),
|
||||
Status: &nbpeer.PeerStatus{Connected: i%2 == 0, LastSeen: time.Now()},
|
||||
})
|
||||
|
||||
@@ -185,7 +185,7 @@ type Store interface {
|
||||
SaveNameServerGroup(ctx context.Context, nameServerGroup *dns.NameServerGroup) error
|
||||
DeleteNameServerGroup(ctx context.Context, accountID, nameServerGroupID string) error
|
||||
|
||||
GetTakenIPs(ctx context.Context, lockStrength LockingStrength, accountId string) ([]net.IP, error)
|
||||
GetTakenIPs(ctx context.Context, lockStrength LockingStrength, accountId string) ([]netip.Addr, error)
|
||||
IncrementNetworkSerial(ctx context.Context, accountId string) error
|
||||
GetAccountNetwork(ctx context.Context, lockStrength LockingStrength, accountId string) (*types.Network, error)
|
||||
|
||||
@@ -225,6 +225,7 @@ type Store interface {
|
||||
IsPrimaryAccount(ctx context.Context, accountID string) (bool, string, error)
|
||||
MarkAccountPrimary(ctx context.Context, accountID string) error
|
||||
UpdateAccountNetwork(ctx context.Context, accountID string, ipNet net.IPNet) error
|
||||
UpdateAccountNetworkV6(ctx context.Context, accountID string, ipNet net.IPNet) error
|
||||
GetPolicyRulesByResourceID(ctx context.Context, lockStrength LockingStrength, accountID string, peerID string) ([]*types.PolicyRule, error)
|
||||
|
||||
// SetFieldEncrypt sets the field encryptor for encrypting sensitive user data.
|
||||
|
||||
@@ -7,6 +7,7 @@ package store
|
||||
import (
|
||||
context "context"
|
||||
net "net"
|
||||
netip "net/netip"
|
||||
reflect "reflect"
|
||||
time "time"
|
||||
|
||||
@@ -2138,10 +2139,10 @@ func (mr *MockStoreMockRecorder) GetStoreEngine() *gomock.Call {
|
||||
}
|
||||
|
||||
// GetTakenIPs mocks base method.
|
||||
func (m *MockStore) GetTakenIPs(ctx context.Context, lockStrength LockingStrength, accountId string) ([]net.IP, error) {
|
||||
func (m *MockStore) GetTakenIPs(ctx context.Context, lockStrength LockingStrength, accountId string) ([]netip.Addr, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetTakenIPs", ctx, lockStrength, accountId)
|
||||
ret0, _ := ret[0].([]net.IP)
|
||||
ret0, _ := ret[0].([]netip.Addr)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@@ -2952,6 +2953,20 @@ func (mr *MockStoreMockRecorder) UpdateAccountNetwork(ctx, accountID, ipNet inte
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAccountNetwork", reflect.TypeOf((*MockStore)(nil).UpdateAccountNetwork), ctx, accountID, ipNet)
|
||||
}
|
||||
|
||||
// UpdateAccountNetworkV6 mocks base method.
|
||||
func (m *MockStore) UpdateAccountNetworkV6(ctx context.Context, accountID string, ipNet net.IPNet) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "UpdateAccountNetworkV6", ctx, accountID, ipNet)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// UpdateAccountNetworkV6 indicates an expected call of UpdateAccountNetworkV6.
|
||||
func (mr *MockStoreMockRecorder) UpdateAccountNetworkV6(ctx, accountID, ipNet interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAccountNetworkV6", reflect.TypeOf((*MockStore)(nil).UpdateAccountNetworkV6), ctx, accountID, ipNet)
|
||||
}
|
||||
|
||||
// UpdateCustomDomain mocks base method.
|
||||
func (m *MockStore) UpdateCustomDomain(ctx context.Context, accountID string, d *domain.Domain) (*domain.Domain, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
Reference in New Issue
Block a user