Skip to content

Commit f0083cf

Browse files
committed
Fix extraneous commas and quotes in README. Implement Stringer interface for PeerConfig structs. Break out ValToPtr functions into a testutils package.
1 parent fce47fc commit f0083cf

File tree

5 files changed

+220
-53
lines changed

5 files changed

+220
-53
lines changed

docs/bgp.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,10 @@ kubectl annotate node <kube-node> \
9595
kube-router.io/peers="$(cat <<'EOF'
9696
- remoteip: 192.168.1.99
9797
remoteasn: 65000
98-
password: U2VjdXJlUGFzc3dvcmQK,
98+
password: U2VjdXJlUGFzc3dvcmQK
9999
- remoteip: 192.168.1.100
100-
remoteasn: 65000'
101-
password: U2VjdXJlUGFzc3dvcmQK,
100+
remoteasn: 65000
101+
password: U2VjdXJlUGFzc3dvcmQK
102102
EOF
103103
)"
104104
```

internal/testutils/pointers.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package testutils
2+
3+
import (
4+
"net"
5+
6+
"github.com/cloudnativelabs/kube-router/v2/pkg/utils"
7+
)
8+
9+
type TestValue interface {
10+
string | uint32 | net.IP | utils.Base64String
11+
}
12+
13+
func ValToPtr[V TestValue](v V) *V {
14+
return &v
15+
}
16+
17+
func PtrToVal[V TestValue](v *V) V {
18+
if v == nil {
19+
return *new(V)
20+
}
21+
return *v
22+
}

pkg/bgp/peer_config.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"net"
77
"strconv"
8+
"strings"
89

910
"github.com/cloudnativelabs/kube-router/v2/pkg/options"
1011
"github.com/cloudnativelabs/kube-router/v2/pkg/utils"
@@ -19,6 +20,25 @@ type PeerConfig struct {
1920
RemoteIP *net.IP `yaml:"remoteip"`
2021
}
2122

23+
// Custom Stringer to prevent leaking passwords when printed
24+
func (p PeerConfig) String() string {
25+
var fields []string
26+
27+
if p.LocalIP != nil {
28+
fields = append(fields, fmt.Sprintf("LocalIP: %s", *p.LocalIP))
29+
}
30+
if p.Port != nil {
31+
fields = append(fields, fmt.Sprintf("Port: %d", *p.Port))
32+
}
33+
if p.RemoteASN != nil {
34+
fields = append(fields, fmt.Sprintf("RemoteASN: %d", *p.RemoteASN))
35+
}
36+
if p.RemoteIP != nil {
37+
fields = append(fields, fmt.Sprintf("RemoteIP: %v", *p.RemoteIP))
38+
}
39+
return fmt.Sprintf("PeerConfig{%s}", strings.Join(fields, ", "))
40+
}
41+
2242
func (p *PeerConfig) UnmarshalYAML(raw []byte) error {
2343
tmp := struct {
2444
LocalIP *string `yaml:"localip"`
@@ -110,6 +130,15 @@ func (p PeerConfigs) RemoteIPStrings() []string {
110130
return remoteIPs
111131
}
112132

133+
// Prints the PeerConfigs without the passwords leaking
134+
func (p PeerConfigs) String() string {
135+
pcs := make([]string, len(p))
136+
for i, pc := range p {
137+
pcs[i] = pc.String()
138+
}
139+
return fmt.Sprintf("PeerConfigs[%s]", strings.Join(pcs, ","))
140+
}
141+
113142
func (p *PeerConfigs) UnmarshalYAML(raw []byte) error {
114143
type tmpPeerConfigs PeerConfigs
115144
tmp := (*tmpPeerConfigs)(p)

pkg/bgp/peer_config_test.go

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,141 @@
11
package bgp
22

33
import (
4+
"net"
45
"testing"
56

7+
"github.com/cloudnativelabs/kube-router/v2/internal/testutils"
8+
"github.com/cloudnativelabs/kube-router/v2/pkg/utils"
69
"github.com/stretchr/testify/assert"
710
)
811

12+
func TestPeerConfig_String(t *testing.T) {
13+
tests := []struct {
14+
name string
15+
config PeerConfig
16+
expected string
17+
}{
18+
{
19+
name: "empty PeerConfig",
20+
config: PeerConfig{},
21+
expected: "PeerConfig{}",
22+
},
23+
{
24+
name: "LocalIP",
25+
config: PeerConfig{
26+
LocalIP: testutils.ValToPtr("192.168.1.1"),
27+
},
28+
expected: "PeerConfig{LocalIP: 192.168.1.1}",
29+
},
30+
{
31+
name: "Port",
32+
config: PeerConfig{
33+
Port: testutils.ValToPtr(uint32(179)),
34+
},
35+
expected: "PeerConfig{Port: 179}",
36+
},
37+
{
38+
name: "RemoteASN",
39+
config: PeerConfig{
40+
RemoteASN: testutils.ValToPtr(uint32(65000)),
41+
},
42+
expected: "PeerConfig{RemoteASN: 65000}",
43+
},
44+
{
45+
name: "RemoteIP",
46+
config: PeerConfig{
47+
RemoteIP: testutils.ValToPtr(net.ParseIP("10.0.0.1")),
48+
},
49+
expected: "PeerConfig{RemoteIP: 10.0.0.1}",
50+
},
51+
{
52+
name: "RemoteIP with IPv6",
53+
config: PeerConfig{
54+
RemoteIP: testutils.ValToPtr(net.ParseIP("2001:db8::1")),
55+
},
56+
expected: "PeerConfig{RemoteIP: 2001:db8::1}",
57+
},
58+
{
59+
name: "Password - should not be printed",
60+
config: PeerConfig{
61+
Password: testutils.ValToPtr(utils.Base64String("password")),
62+
},
63+
expected: "PeerConfig{}",
64+
},
65+
{
66+
name: "all fields - Password should not be printed",
67+
config: PeerConfig{
68+
LocalIP: testutils.ValToPtr("192.168.1.1"),
69+
Password: testutils.ValToPtr(utils.Base64String("password")),
70+
Port: testutils.ValToPtr(uint32(179)),
71+
RemoteASN: testutils.ValToPtr(uint32(65000)),
72+
RemoteIP: testutils.ValToPtr(net.ParseIP("10.0.0.1")),
73+
},
74+
expected: "PeerConfig{LocalIP: 192.168.1.1, Port: 179, RemoteASN: 65000, RemoteIP: 10.0.0.1}",
75+
},
76+
}
77+
78+
for _, tt := range tests {
79+
t.Run(tt.name, func(t *testing.T) {
80+
result := tt.config.String()
81+
assert.Equal(t, tt.expected, result)
82+
})
83+
}
84+
}
85+
86+
func TestPeerConfigs_String(t *testing.T) {
87+
tests := []struct {
88+
name string
89+
configs PeerConfigs
90+
expected string
91+
}{
92+
{
93+
name: "empty PeerConfigs",
94+
configs: PeerConfigs{},
95+
expected: "PeerConfigs[]",
96+
},
97+
{
98+
name: "PeerConfig - password should not be printed",
99+
configs: PeerConfigs{
100+
{
101+
LocalIP: testutils.ValToPtr("192.168.1.1"),
102+
Password: testutils.ValToPtr(utils.Base64String("secret")),
103+
Port: testutils.ValToPtr(uint32(179)),
104+
RemoteASN: testutils.ValToPtr(uint32(65000)),
105+
RemoteIP: testutils.ValToPtr(net.ParseIP("10.0.0.1")),
106+
},
107+
},
108+
expected: "PeerConfigs[PeerConfig{LocalIP: 192.168.1.1, Port: 179, RemoteASN: 65000, RemoteIP: 10.0.0.1}]",
109+
},
110+
{
111+
name: "multiple PeerConfigs - passwords should not be printed",
112+
configs: PeerConfigs{
113+
{
114+
LocalIP: testutils.ValToPtr("192.168.1.1"),
115+
Password: testutils.ValToPtr(utils.Base64String("secret")),
116+
RemoteASN: testutils.ValToPtr(uint32(65000)),
117+
RemoteIP: testutils.ValToPtr(net.ParseIP("10.0.0.1")),
118+
},
119+
{
120+
Port: testutils.ValToPtr(uint32(1790)),
121+
RemoteASN: testutils.ValToPtr(uint32(65001)),
122+
RemoteIP: testutils.ValToPtr(net.ParseIP("10.0.0.2")),
123+
},
124+
{
125+
RemoteIP: testutils.ValToPtr(net.ParseIP("10.0.0.3")),
126+
},
127+
},
128+
expected: "PeerConfigs[PeerConfig{LocalIP: 192.168.1.1, RemoteASN: 65000, RemoteIP: 10.0.0.1},PeerConfig{Port: 1790, RemoteASN: 65001, RemoteIP: 10.0.0.2},PeerConfig{RemoteIP: 10.0.0.3}]",
129+
},
130+
}
131+
132+
for _, tt := range tests {
133+
t.Run(tt.name, func(t *testing.T) {
134+
assert.Equal(t, tt.expected, tt.configs.String())
135+
})
136+
}
137+
}
138+
9139
func Test_NewPeerConfigs(t *testing.T) {
10140
tcs := []struct {
11141
name string

pkg/controllers/routing/network_routes_controller_test.go

Lines changed: 36 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"testing"
1111
"time"
1212

13+
"github.com/cloudnativelabs/kube-router/v2/internal/testutils"
1314
"github.com/cloudnativelabs/kube-router/v2/pkg/bgp"
1415
"github.com/cloudnativelabs/kube-router/v2/pkg/k8s/indexers"
1516
"github.com/cloudnativelabs/kube-router/v2/pkg/utils"
@@ -1822,11 +1823,11 @@ func Test_nodeHasEndpointsForService(t *testing.T) {
18221823
Endpoints: []discoveryv1.Endpoint{
18231824
{
18241825
Addresses: []string{"172.20.1.1"},
1825-
NodeName: valToPtr("node-1"),
1826+
NodeName: testutils.ValToPtr("node-1"),
18261827
},
18271828
{
18281829
Addresses: []string{"172.20.1.2"},
1829-
NodeName: valToPtr("node-2"),
1830+
NodeName: testutils.ValToPtr("node-2"),
18301831
},
18311832
},
18321833
},
@@ -1867,11 +1868,11 @@ func Test_nodeHasEndpointsForService(t *testing.T) {
18671868
Endpoints: []discoveryv1.Endpoint{
18681869
{
18691870
Addresses: []string{"172.20.1.1"},
1870-
NodeName: valToPtr("node-2"),
1871+
NodeName: testutils.ValToPtr("node-2"),
18711872
},
18721873
{
18731874
Addresses: []string{"172.20.1.2"},
1874-
NodeName: valToPtr("node-3"),
1875+
NodeName: testutils.ValToPtr("node-3"),
18751876
},
18761877
},
18771878
},
@@ -2650,16 +2651,16 @@ func Test_bgpPeerConfigsFromAnnotations(t *testing.T) {
26502651
},
26512652
bgp.PeerConfigs{
26522653
bgp.PeerConfig{
2653-
RemoteIP: valToPtr(net.ParseIP("10.0.0.1")),
2654-
RemoteASN: valToPtr(uint32(64640)),
2655-
Password: valToPtr(utils.Base64String("password")),
2656-
LocalIP: valToPtr("192.168.0.1"),
2654+
RemoteIP: testutils.ValToPtr(net.ParseIP("10.0.0.1")),
2655+
RemoteASN: testutils.ValToPtr(uint32(64640)),
2656+
Password: testutils.ValToPtr(utils.Base64String("password")),
2657+
LocalIP: testutils.ValToPtr("192.168.0.1"),
26572658
},
26582659
bgp.PeerConfig{
2659-
RemoteIP: valToPtr(net.ParseIP("10.0.0.2")),
2660-
RemoteASN: valToPtr(uint32(64641)),
2661-
Password: valToPtr(utils.Base64String("password")),
2662-
LocalIP: valToPtr("192.168.0.2"),
2660+
RemoteIP: testutils.ValToPtr(net.ParseIP("10.0.0.2")),
2661+
RemoteASN: testutils.ValToPtr(uint32(64641)),
2662+
Password: testutils.ValToPtr(utils.Base64String("password")),
2663+
LocalIP: testutils.ValToPtr("192.168.0.2"),
26632664
},
26642665
},
26652666
false,
@@ -2676,14 +2677,14 @@ func Test_bgpPeerConfigsFromAnnotations(t *testing.T) {
26762677
},
26772678
bgp.PeerConfigs{
26782679
bgp.PeerConfig{
2679-
RemoteIP: valToPtr(net.ParseIP("10.0.0.1")),
2680-
RemoteASN: valToPtr(uint32(64640)),
2680+
RemoteIP: testutils.ValToPtr(net.ParseIP("10.0.0.1")),
2681+
RemoteASN: testutils.ValToPtr(uint32(64640)),
26812682
},
26822683
bgp.PeerConfig{
2683-
RemoteIP: valToPtr(net.ParseIP("10.0.0.2")),
2684-
RemoteASN: valToPtr(uint32(64641)),
2685-
Password: valToPtr(utils.Base64String("password")),
2686-
LocalIP: valToPtr("192.168.0.2"),
2684+
RemoteIP: testutils.ValToPtr(net.ParseIP("10.0.0.2")),
2685+
RemoteASN: testutils.ValToPtr(uint32(64641)),
2686+
Password: testutils.ValToPtr(utils.Base64String("password")),
2687+
LocalIP: testutils.ValToPtr("192.168.0.2"),
26872688
},
26882689
},
26892690
true,
@@ -2698,16 +2699,16 @@ func Test_bgpPeerConfigsFromAnnotations(t *testing.T) {
26982699
},
26992700
bgp.PeerConfigs{
27002701
bgp.PeerConfig{
2701-
RemoteIP: valToPtr(net.ParseIP("10.0.0.1")),
2702-
RemoteASN: valToPtr(uint32(64640)),
2703-
Password: valToPtr(utils.Base64String("password")),
2704-
LocalIP: valToPtr("192.168.0.1"),
2702+
RemoteIP: testutils.ValToPtr(net.ParseIP("10.0.0.1")),
2703+
RemoteASN: testutils.ValToPtr(uint32(64640)),
2704+
Password: testutils.ValToPtr(utils.Base64String("password")),
2705+
LocalIP: testutils.ValToPtr("192.168.0.1"),
27052706
},
27062707
bgp.PeerConfig{
2707-
RemoteIP: valToPtr(net.ParseIP("10.0.0.2")),
2708-
RemoteASN: valToPtr(uint32(64641)),
2709-
Password: valToPtr(utils.Base64String("password")),
2710-
LocalIP: valToPtr("192.168.0.2"),
2708+
RemoteIP: testutils.ValToPtr(net.ParseIP("10.0.0.2")),
2709+
RemoteASN: testutils.ValToPtr(uint32(64641)),
2710+
Password: testutils.ValToPtr(utils.Base64String("password")),
2711+
LocalIP: testutils.ValToPtr("192.168.0.2"),
27112712
},
27122713
},
27132714
false,
@@ -2722,16 +2723,16 @@ func Test_bgpPeerConfigsFromAnnotations(t *testing.T) {
27222723
},
27232724
bgp.PeerConfigs{
27242725
bgp.PeerConfig{
2725-
RemoteIP: valToPtr(net.ParseIP("10.0.0.1")),
2726-
RemoteASN: valToPtr(uint32(64640)),
2727-
Password: valToPtr(utils.Base64String("password")),
2728-
LocalIP: valToPtr("192.168.0.1"),
2726+
RemoteIP: testutils.ValToPtr(net.ParseIP("10.0.0.1")),
2727+
RemoteASN: testutils.ValToPtr(uint32(64640)),
2728+
Password: testutils.ValToPtr(utils.Base64String("password")),
2729+
LocalIP: testutils.ValToPtr("192.168.0.1"),
27292730
},
27302731
bgp.PeerConfig{
2731-
RemoteIP: valToPtr(net.ParseIP("10.0.0.2")),
2732-
RemoteASN: valToPtr(uint32(64641)),
2733-
Password: valToPtr(utils.Base64String("password")),
2734-
LocalIP: valToPtr("192.168.0.2"),
2732+
RemoteIP: testutils.ValToPtr(net.ParseIP("10.0.0.2")),
2733+
RemoteASN: testutils.ValToPtr(uint32(64641)),
2734+
Password: testutils.ValToPtr(utils.Base64String("password")),
2735+
LocalIP: testutils.ValToPtr("192.168.0.2"),
27352736
},
27362737
},
27372738
true,
@@ -2760,7 +2761,7 @@ func Test_bgpPeerConfigsFromAnnotations(t *testing.T) {
27602761

27612762
for _, tc := range testCases {
27622763
t.Run(tc.name, func(t *testing.T) {
2763-
bgpPeerCfgs, err := bgpPeerConfigsFromAnnotations(tc.nodeAnnotations)
2764+
bgpPeerCfgs, err := bgpPeerConfigsFromAnnotations(tc.nodeAnnotations, "")
27642765
if tc.expectError {
27652766
assert.Error(t, err)
27662767
return
@@ -3018,18 +3019,3 @@ func waitForListerWithTimeout(lister cache.Indexer, timeout time.Duration, t *te
30183019
}
30193020
}
30203021
}
3021-
3022-
type value interface {
3023-
string | uint32 | net.IP | utils.Base64String
3024-
}
3025-
3026-
func valToPtr[V value](v V) *V {
3027-
return &v
3028-
}
3029-
3030-
func ptrToVal[V value](v *V) V {
3031-
if v == nil {
3032-
return *new(V)
3033-
}
3034-
return *v
3035-
}

0 commit comments

Comments
 (0)