mirror of https://github.com/tailscale/tailscale/
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
722 lines
16 KiB
Go
722 lines
16 KiB
Go
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package ipn
|
|
|
|
import (
|
|
"net/netip"
|
|
"testing"
|
|
|
|
"tailscale.com/tailcfg"
|
|
"tailscale.com/types/opt"
|
|
"tailscale.com/types/preftype"
|
|
)
|
|
|
|
// TestConfigVAlpha_ToPrefs_Nil tests nil config handling
|
|
func TestConfigVAlpha_ToPrefs_Nil(t *testing.T) {
|
|
var c *ConfigVAlpha
|
|
mp, err := c.ToPrefs()
|
|
if err != nil {
|
|
t.Errorf("ToPrefs() with nil config should not error: %v", err)
|
|
}
|
|
|
|
// Nil config should produce empty MaskedPrefs
|
|
if mp.WantRunningSet {
|
|
t.Error("nil config should not set WantRunningSet")
|
|
}
|
|
if mp.ControlURLSet {
|
|
t.Error("nil config should not set ControlURLSet")
|
|
}
|
|
}
|
|
|
|
// TestConfigVAlpha_ToPrefs_Empty tests empty config
|
|
func TestConfigVAlpha_ToPrefs_Empty(t *testing.T) {
|
|
c := &ConfigVAlpha{}
|
|
mp, err := c.ToPrefs()
|
|
if err != nil {
|
|
t.Errorf("ToPrefs() with empty config failed: %v", err)
|
|
}
|
|
|
|
// Empty config should still set AdvertiseServicesSet
|
|
if !mp.AdvertiseServicesSet {
|
|
t.Error("AdvertiseServicesSet should be true even for empty config")
|
|
}
|
|
}
|
|
|
|
// TestConfigVAlpha_ToPrefs_WantRunning tests Enabled field
|
|
func TestConfigVAlpha_ToPrefs_WantRunning(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
enabled opt.Bool
|
|
wantRunning bool
|
|
wantRunningSet bool
|
|
}{
|
|
{
|
|
name: "enabled_true",
|
|
enabled: "true",
|
|
wantRunning: true,
|
|
wantRunningSet: true,
|
|
},
|
|
{
|
|
name: "enabled_false",
|
|
enabled: "false",
|
|
wantRunning: false,
|
|
wantRunningSet: true,
|
|
},
|
|
{
|
|
name: "enabled_unset",
|
|
enabled: "",
|
|
wantRunning: true, // defaults to true when unset
|
|
wantRunningSet: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
c := &ConfigVAlpha{
|
|
Enabled: tt.enabled,
|
|
}
|
|
mp, err := c.ToPrefs()
|
|
if err != nil {
|
|
t.Fatalf("ToPrefs() failed: %v", err)
|
|
}
|
|
|
|
if mp.WantRunning != tt.wantRunning {
|
|
t.Errorf("WantRunning = %v, want %v", mp.WantRunning, tt.wantRunning)
|
|
}
|
|
if mp.WantRunningSet != tt.wantRunningSet {
|
|
t.Errorf("WantRunningSet = %v, want %v", mp.WantRunningSet, tt.wantRunningSet)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestConfigVAlpha_ToPrefs_ServerURL tests ServerURL field
|
|
func TestConfigVAlpha_ToPrefs_ServerURL(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
serverURL *string
|
|
wantURL string
|
|
wantSet bool
|
|
}{
|
|
{
|
|
name: "custom_server",
|
|
serverURL: stringPtr("https://custom.example.com"),
|
|
wantURL: "https://custom.example.com",
|
|
wantSet: true,
|
|
},
|
|
{
|
|
name: "nil_server",
|
|
serverURL: nil,
|
|
wantURL: "",
|
|
wantSet: false,
|
|
},
|
|
{
|
|
name: "empty_server",
|
|
serverURL: stringPtr(""),
|
|
wantURL: "",
|
|
wantSet: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
c := &ConfigVAlpha{
|
|
ServerURL: tt.serverURL,
|
|
}
|
|
mp, err := c.ToPrefs()
|
|
if err != nil {
|
|
t.Fatalf("ToPrefs() failed: %v", err)
|
|
}
|
|
|
|
if mp.ControlURL != tt.wantURL {
|
|
t.Errorf("ControlURL = %q, want %q", mp.ControlURL, tt.wantURL)
|
|
}
|
|
if mp.ControlURLSet != tt.wantSet {
|
|
t.Errorf("ControlURLSet = %v, want %v", mp.ControlURLSet, tt.wantSet)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestConfigVAlpha_ToPrefs_AuthKey tests AuthKey field
|
|
func TestConfigVAlpha_ToPrefs_AuthKey(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
authKey *string
|
|
wantLoggedOut bool
|
|
wantSet bool
|
|
}{
|
|
{
|
|
name: "with_authkey",
|
|
authKey: stringPtr("tskey-auth-xxx"),
|
|
wantLoggedOut: false,
|
|
wantSet: true,
|
|
},
|
|
{
|
|
name: "empty_authkey",
|
|
authKey: stringPtr(""),
|
|
wantLoggedOut: false,
|
|
wantSet: false,
|
|
},
|
|
{
|
|
name: "nil_authkey",
|
|
authKey: nil,
|
|
wantLoggedOut: false,
|
|
wantSet: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
c := &ConfigVAlpha{
|
|
AuthKey: tt.authKey,
|
|
}
|
|
mp, err := c.ToPrefs()
|
|
if err != nil {
|
|
t.Fatalf("ToPrefs() failed: %v", err)
|
|
}
|
|
|
|
if mp.LoggedOut != tt.wantLoggedOut {
|
|
t.Errorf("LoggedOut = %v, want %v", mp.LoggedOut, tt.wantLoggedOut)
|
|
}
|
|
if mp.LoggedOutSet != tt.wantSet {
|
|
t.Errorf("LoggedOutSet = %v, want %v", mp.LoggedOutSet, tt.wantSet)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestConfigVAlpha_ToPrefs_OperatorUser tests OperatorUser field
|
|
func TestConfigVAlpha_ToPrefs_OperatorUser(t *testing.T) {
|
|
user := "alice"
|
|
c := &ConfigVAlpha{
|
|
OperatorUser: &user,
|
|
}
|
|
mp, err := c.ToPrefs()
|
|
if err != nil {
|
|
t.Fatalf("ToPrefs() failed: %v", err)
|
|
}
|
|
|
|
if mp.OperatorUser != user {
|
|
t.Errorf("OperatorUser = %q, want %q", mp.OperatorUser, user)
|
|
}
|
|
if !mp.OperatorUserSet {
|
|
t.Error("OperatorUserSet should be true")
|
|
}
|
|
}
|
|
|
|
// TestConfigVAlpha_ToPrefs_Hostname tests Hostname field
|
|
func TestConfigVAlpha_ToPrefs_Hostname(t *testing.T) {
|
|
hostname := "my-machine"
|
|
c := &ConfigVAlpha{
|
|
Hostname: &hostname,
|
|
}
|
|
mp, err := c.ToPrefs()
|
|
if err != nil {
|
|
t.Fatalf("ToPrefs() failed: %v", err)
|
|
}
|
|
|
|
if mp.Hostname != hostname {
|
|
t.Errorf("Hostname = %q, want %q", mp.Hostname, hostname)
|
|
}
|
|
if !mp.HostnameSet {
|
|
t.Error("HostnameSet should be true")
|
|
}
|
|
}
|
|
|
|
// TestConfigVAlpha_ToPrefs_DNS tests AcceptDNS field
|
|
func TestConfigVAlpha_ToPrefs_DNS(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
acceptDNS opt.Bool
|
|
wantCorpDNS bool
|
|
wantSet bool
|
|
}{
|
|
{
|
|
name: "accept_dns_true",
|
|
acceptDNS: "true",
|
|
wantCorpDNS: true,
|
|
wantSet: true,
|
|
},
|
|
{
|
|
name: "accept_dns_false",
|
|
acceptDNS: "false",
|
|
wantCorpDNS: false,
|
|
wantSet: true,
|
|
},
|
|
{
|
|
name: "accept_dns_unset",
|
|
acceptDNS: "",
|
|
wantCorpDNS: false,
|
|
wantSet: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
c := &ConfigVAlpha{
|
|
AcceptDNS: tt.acceptDNS,
|
|
}
|
|
mp, err := c.ToPrefs()
|
|
if err != nil {
|
|
t.Fatalf("ToPrefs() failed: %v", err)
|
|
}
|
|
|
|
if mp.CorpDNS != tt.wantCorpDNS {
|
|
t.Errorf("CorpDNS = %v, want %v", mp.CorpDNS, tt.wantCorpDNS)
|
|
}
|
|
if mp.CorpDNSSet != tt.wantSet {
|
|
t.Errorf("CorpDNSSet = %v, want %v", mp.CorpDNSSet, tt.wantSet)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestConfigVAlpha_ToPrefs_Routes tests AcceptRoutes field
|
|
func TestConfigVAlpha_ToPrefs_Routes(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
acceptRoutes opt.Bool
|
|
wantRouteAll bool
|
|
wantRouteSet bool
|
|
}{
|
|
{
|
|
name: "accept_routes_true",
|
|
acceptRoutes: "true",
|
|
wantRouteAll: true,
|
|
wantRouteSet: true,
|
|
},
|
|
{
|
|
name: "accept_routes_false",
|
|
acceptRoutes: "false",
|
|
wantRouteAll: false,
|
|
wantRouteSet: true,
|
|
},
|
|
{
|
|
name: "accept_routes_unset",
|
|
acceptRoutes: "",
|
|
wantRouteAll: false,
|
|
wantRouteSet: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
c := &ConfigVAlpha{
|
|
AcceptRoutes: tt.acceptRoutes,
|
|
}
|
|
mp, err := c.ToPrefs()
|
|
if err != nil {
|
|
t.Fatalf("ToPrefs() failed: %v", err)
|
|
}
|
|
|
|
if mp.RouteAll != tt.wantRouteAll {
|
|
t.Errorf("RouteAll = %v, want %v", mp.RouteAll, tt.wantRouteAll)
|
|
}
|
|
if mp.RouteAllSet != tt.wantRouteSet {
|
|
t.Errorf("RouteAllSet = %v, want %v", mp.RouteAllSet, tt.wantRouteSet)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestConfigVAlpha_ToPrefs_ExitNode tests ExitNode field
|
|
func TestConfigVAlpha_ToPrefs_ExitNode(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
exitNode *string
|
|
wantIP netip.Addr
|
|
wantIPSet bool
|
|
wantID tailcfg.StableNodeID
|
|
wantIDSet bool
|
|
}{
|
|
{
|
|
name: "exit_node_ip",
|
|
exitNode: stringPtr("100.64.0.1"),
|
|
wantIP: netip.MustParseAddr("100.64.0.1"),
|
|
wantIPSet: true,
|
|
wantIDSet: false,
|
|
},
|
|
{
|
|
name: "exit_node_stable_id",
|
|
exitNode: stringPtr("node-abc123"),
|
|
wantID: "node-abc123",
|
|
wantIDSet: true,
|
|
wantIPSet: false,
|
|
},
|
|
{
|
|
name: "exit_node_nil",
|
|
exitNode: nil,
|
|
wantIPSet: false,
|
|
wantIDSet: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
c := &ConfigVAlpha{
|
|
ExitNode: tt.exitNode,
|
|
}
|
|
mp, err := c.ToPrefs()
|
|
if err != nil {
|
|
t.Fatalf("ToPrefs() failed: %v", err)
|
|
}
|
|
|
|
if mp.ExitNodeIPSet != tt.wantIPSet {
|
|
t.Errorf("ExitNodeIPSet = %v, want %v", mp.ExitNodeIPSet, tt.wantIPSet)
|
|
}
|
|
if tt.wantIPSet && mp.ExitNodeIP != tt.wantIP {
|
|
t.Errorf("ExitNodeIP = %v, want %v", mp.ExitNodeIP, tt.wantIP)
|
|
}
|
|
|
|
if mp.ExitNodeIDSet != tt.wantIDSet {
|
|
t.Errorf("ExitNodeIDSet = %v, want %v", mp.ExitNodeIDSet, tt.wantIDSet)
|
|
}
|
|
if tt.wantIDSet && mp.ExitNodeID != tt.wantID {
|
|
t.Errorf("ExitNodeID = %v, want %v", mp.ExitNodeID, tt.wantID)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestConfigVAlpha_ToPrefs_AllowLANWhileUsingExitNode tests the field
|
|
func TestConfigVAlpha_ToPrefs_AllowLANWhileUsingExitNode(t *testing.T) {
|
|
c := &ConfigVAlpha{
|
|
AllowLANWhileUsingExitNode: "true",
|
|
}
|
|
mp, err := c.ToPrefs()
|
|
if err != nil {
|
|
t.Fatalf("ToPrefs() failed: %v", err)
|
|
}
|
|
|
|
if !mp.ExitNodeAllowLANAccess {
|
|
t.Error("ExitNodeAllowLANAccess should be true")
|
|
}
|
|
if !mp.ExitNodeAllowLANAccessSet {
|
|
t.Error("ExitNodeAllowLANAccessSet should be true")
|
|
}
|
|
}
|
|
|
|
// TestConfigVAlpha_ToPrefs_AdvertiseRoutes tests AdvertiseRoutes field
|
|
func TestConfigVAlpha_ToPrefs_AdvertiseRoutes(t *testing.T) {
|
|
routes := []netip.Prefix{
|
|
netip.MustParsePrefix("10.0.0.0/24"),
|
|
netip.MustParsePrefix("192.168.1.0/24"),
|
|
}
|
|
|
|
c := &ConfigVAlpha{
|
|
AdvertiseRoutes: routes,
|
|
}
|
|
mp, err := c.ToPrefs()
|
|
if err != nil {
|
|
t.Fatalf("ToPrefs() failed: %v", err)
|
|
}
|
|
|
|
if !mp.AdvertiseRoutesSet {
|
|
t.Error("AdvertiseRoutesSet should be true")
|
|
}
|
|
if len(mp.AdvertiseRoutes) != 2 {
|
|
t.Errorf("AdvertiseRoutes length = %d, want 2", len(mp.AdvertiseRoutes))
|
|
}
|
|
}
|
|
|
|
// TestConfigVAlpha_ToPrefs_NetfilterMode tests NetfilterMode field
|
|
func TestConfigVAlpha_ToPrefs_NetfilterMode(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
mode *string
|
|
wantErr bool
|
|
wantSet bool
|
|
}{
|
|
{
|
|
name: "mode_on",
|
|
mode: stringPtr("on"),
|
|
wantErr: false,
|
|
wantSet: true,
|
|
},
|
|
{
|
|
name: "mode_off",
|
|
mode: stringPtr("off"),
|
|
wantErr: false,
|
|
wantSet: true,
|
|
},
|
|
{
|
|
name: "mode_nodivert",
|
|
mode: stringPtr("nodivert"),
|
|
wantErr: false,
|
|
wantSet: true,
|
|
},
|
|
{
|
|
name: "invalid_mode",
|
|
mode: stringPtr("invalid"),
|
|
wantErr: true,
|
|
wantSet: false,
|
|
},
|
|
{
|
|
name: "nil_mode",
|
|
mode: nil,
|
|
wantErr: false,
|
|
wantSet: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
c := &ConfigVAlpha{
|
|
NetfilterMode: tt.mode,
|
|
}
|
|
mp, err := c.ToPrefs()
|
|
|
|
if tt.wantErr && err == nil {
|
|
t.Error("expected error for invalid NetfilterMode")
|
|
}
|
|
if !tt.wantErr && err != nil {
|
|
t.Errorf("unexpected error: %v", err)
|
|
}
|
|
|
|
if !tt.wantErr && mp.NetfilterModeSet != tt.wantSet {
|
|
t.Errorf("NetfilterModeSet = %v, want %v", mp.NetfilterModeSet, tt.wantSet)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestConfigVAlpha_ToPrefs_BooleanFlags tests various boolean flags
|
|
func TestConfigVAlpha_ToPrefs_BooleanFlags(t *testing.T) {
|
|
c := &ConfigVAlpha{
|
|
PostureChecking: "true",
|
|
RunSSHServer: "true",
|
|
RunWebClient: "false",
|
|
ShieldsUp: "true",
|
|
DisableSNAT: "true",
|
|
NoStatefulFiltering: "true",
|
|
}
|
|
mp, err := c.ToPrefs()
|
|
if err != nil {
|
|
t.Fatalf("ToPrefs() failed: %v", err)
|
|
}
|
|
|
|
if !mp.PostureChecking {
|
|
t.Error("PostureChecking should be true")
|
|
}
|
|
if !mp.PostureCheckingSet {
|
|
t.Error("PostureCheckingSet should be true")
|
|
}
|
|
|
|
if !mp.RunSSH {
|
|
t.Error("RunSSH should be true")
|
|
}
|
|
if !mp.RunSSHSet {
|
|
t.Error("RunSSHSet should be true")
|
|
}
|
|
|
|
if mp.RunWebClient {
|
|
t.Error("RunWebClient should be false")
|
|
}
|
|
if !mp.RunWebClientSet {
|
|
t.Error("RunWebClientSet should be true")
|
|
}
|
|
|
|
if !mp.ShieldsUp {
|
|
t.Error("ShieldsUp should be true")
|
|
}
|
|
if !mp.ShieldsUpSet {
|
|
t.Error("ShieldsUpSet should be true")
|
|
}
|
|
|
|
if !mp.NoSNAT {
|
|
t.Error("NoSNAT should be true")
|
|
}
|
|
}
|
|
|
|
// TestConfigVAlpha_ToPrefs_AdvertiseServices tests AdvertiseServices field
|
|
func TestConfigVAlpha_ToPrefs_AdvertiseServices(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
services []string
|
|
wantLen int
|
|
}{
|
|
{
|
|
name: "multiple_services",
|
|
services: []string{"service1", "service2", "service3"},
|
|
wantLen: 3,
|
|
},
|
|
{
|
|
name: "single_service",
|
|
services: []string{"service1"},
|
|
wantLen: 1,
|
|
},
|
|
{
|
|
name: "empty_services",
|
|
services: []string{},
|
|
wantLen: 0,
|
|
},
|
|
{
|
|
name: "nil_services",
|
|
services: nil,
|
|
wantLen: 0,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
c := &ConfigVAlpha{
|
|
AdvertiseServices: tt.services,
|
|
}
|
|
mp, err := c.ToPrefs()
|
|
if err != nil {
|
|
t.Fatalf("ToPrefs() failed: %v", err)
|
|
}
|
|
|
|
// AdvertiseServicesSet should always be true
|
|
if !mp.AdvertiseServicesSet {
|
|
t.Error("AdvertiseServicesSet should always be true")
|
|
}
|
|
|
|
if len(mp.AdvertiseServices) != tt.wantLen {
|
|
t.Errorf("AdvertiseServices length = %d, want %d", len(mp.AdvertiseServices), tt.wantLen)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestConfigVAlpha_ToPrefs_AutoUpdate tests AutoUpdate field
|
|
func TestConfigVAlpha_ToPrefs_AutoUpdate(t *testing.T) {
|
|
c := &ConfigVAlpha{
|
|
AutoUpdate: &AutoUpdatePrefs{
|
|
Apply: opt.NewBool(true),
|
|
Check: opt.NewBool(true),
|
|
},
|
|
}
|
|
mp, err := c.ToPrefs()
|
|
if err != nil {
|
|
t.Fatalf("ToPrefs() failed: %v", err)
|
|
}
|
|
|
|
if !mp.AutoUpdateSet.ApplySet {
|
|
t.Error("AutoUpdateSet.ApplySet should be true")
|
|
}
|
|
if !mp.AutoUpdateSet.CheckSet {
|
|
t.Error("AutoUpdateSet.CheckSet should be true")
|
|
}
|
|
}
|
|
|
|
// TestConfigVAlpha_ToPrefs_AppConnector tests AppConnector field
|
|
func TestConfigVAlpha_ToPrefs_AppConnector(t *testing.T) {
|
|
c := &ConfigVAlpha{
|
|
AppConnector: &AppConnectorPrefs{
|
|
Advertise: true,
|
|
},
|
|
}
|
|
mp, err := c.ToPrefs()
|
|
if err != nil {
|
|
t.Fatalf("ToPrefs() failed: %v", err)
|
|
}
|
|
|
|
if !mp.AppConnectorSet {
|
|
t.Error("AppConnectorSet should be true")
|
|
}
|
|
if !mp.AppConnector.Advertise {
|
|
t.Error("AppConnector.Advertise should be true")
|
|
}
|
|
}
|
|
|
|
// TestConfigVAlpha_ToPrefs_StaticEndpoints tests StaticEndpoints field
|
|
func TestConfigVAlpha_ToPrefs_StaticEndpoints(t *testing.T) {
|
|
endpoints := []netip.AddrPort{
|
|
netip.MustParseAddrPort("1.2.3.4:5678"),
|
|
netip.MustParseAddrPort("[::1]:9999"),
|
|
}
|
|
|
|
c := &ConfigVAlpha{
|
|
StaticEndpoints: endpoints,
|
|
}
|
|
mp, err := c.ToPrefs()
|
|
if err != nil {
|
|
t.Fatalf("ToPrefs() failed: %v", err)
|
|
}
|
|
|
|
// Note: StaticEndpoints might not be directly set in MaskedPrefs
|
|
// This test verifies the config accepts the field
|
|
_ = mp
|
|
}
|
|
|
|
// TestConfigVAlpha_ToPrefs_ComplexConfig tests a fully populated config
|
|
func TestConfigVAlpha_ToPrefs_ComplexConfig(t *testing.T) {
|
|
serverURL := "https://custom.example.com"
|
|
authKey := "tskey-auth-xxx"
|
|
operator := "alice"
|
|
hostname := "my-machine"
|
|
exitNode := "100.64.0.1"
|
|
mode := "on"
|
|
|
|
c := &ConfigVAlpha{
|
|
Version: "alpha0",
|
|
Locked: "true",
|
|
ServerURL: &serverURL,
|
|
AuthKey: &authKey,
|
|
Enabled: "true",
|
|
OperatorUser: &operator,
|
|
Hostname: &hostname,
|
|
AcceptDNS: "true",
|
|
AcceptRoutes: "true",
|
|
ExitNode: &exitNode,
|
|
AllowLANWhileUsingExitNode: "true",
|
|
AdvertiseRoutes: []netip.Prefix{
|
|
netip.MustParsePrefix("10.0.0.0/24"),
|
|
},
|
|
DisableSNAT: "false",
|
|
AdvertiseServices: []string{"service1", "service2"},
|
|
NetfilterMode: &mode,
|
|
NoStatefulFiltering: "false",
|
|
PostureChecking: "true",
|
|
RunSSHServer: "true",
|
|
RunWebClient: "false",
|
|
ShieldsUp: "false",
|
|
AppConnector: &AppConnectorPrefs{
|
|
Advertise: true,
|
|
},
|
|
AutoUpdate: &AutoUpdatePrefs{
|
|
Apply: opt.NewBool(true),
|
|
Check: opt.NewBool(true),
|
|
},
|
|
}
|
|
|
|
mp, err := c.ToPrefs()
|
|
if err != nil {
|
|
t.Fatalf("ToPrefs() failed: %v", err)
|
|
}
|
|
|
|
// Verify critical fields are set
|
|
if !mp.WantRunning {
|
|
t.Error("WantRunning should be true")
|
|
}
|
|
if mp.ControlURL != serverURL {
|
|
t.Errorf("ControlURL = %q, want %q", mp.ControlURL, serverURL)
|
|
}
|
|
if mp.OperatorUser != operator {
|
|
t.Errorf("OperatorUser = %q, want %q", mp.OperatorUser, operator)
|
|
}
|
|
if mp.Hostname != hostname {
|
|
t.Errorf("Hostname = %q, want %q", mp.Hostname, hostname)
|
|
}
|
|
if !mp.CorpDNS {
|
|
t.Error("CorpDNS should be true")
|
|
}
|
|
if !mp.RouteAll {
|
|
t.Error("RouteAll should be true")
|
|
}
|
|
if len(mp.AdvertiseRoutes) != 1 {
|
|
t.Errorf("AdvertiseRoutes length = %d, want 1", len(mp.AdvertiseRoutes))
|
|
}
|
|
if len(mp.AdvertiseServices) != 2 {
|
|
t.Errorf("AdvertiseServices length = %d, want 2", len(mp.AdvertiseServices))
|
|
}
|
|
}
|
|
|
|
// Helper function
|
|
func stringPtr(s string) *string {
|
|
return &s
|
|
}
|