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.
176 lines
6.5 KiB
Go
176 lines
6.5 KiB
Go
2 months ago
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||
|
|
||
|
//go:build linux
|
||
|
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"net/netip"
|
||
|
"reflect"
|
||
|
"testing"
|
||
|
|
||
|
"tailscale.com/kube/egressservices"
|
||
|
)
|
||
|
|
||
|
func Test_updatesForSvc(t *testing.T) {
|
||
|
tailnetIPv4, tailnetIPv6 := netip.MustParseAddr("100.99.99.99"), netip.MustParseAddr("fd7a:115c:a1e0::701:b62a")
|
||
|
tailnetIPv4_1, tailnetIPv6_1 := netip.MustParseAddr("100.88.88.88"), netip.MustParseAddr("fd7a:115c:a1e0::4101:512f")
|
||
|
ports := map[egressservices.PortMap]struct{}{{Protocol: "tcp", MatchPort: 4003, TargetPort: 80}: {}}
|
||
|
ports1 := map[egressservices.PortMap]struct{}{{Protocol: "udp", MatchPort: 4004, TargetPort: 53}: {}}
|
||
|
ports2 := map[egressservices.PortMap]struct{}{{Protocol: "tcp", MatchPort: 4003, TargetPort: 80}: {},
|
||
|
{Protocol: "tcp", MatchPort: 4005, TargetPort: 443}: {}}
|
||
|
fqdnSpec := egressservices.Config{
|
||
|
TailnetTarget: egressservices.TailnetTarget{FQDN: "test"},
|
||
|
Ports: ports,
|
||
|
}
|
||
|
fqdnSpec1 := egressservices.Config{
|
||
|
TailnetTarget: egressservices.TailnetTarget{FQDN: "test"},
|
||
|
Ports: ports1,
|
||
|
}
|
||
|
fqdnSpec2 := egressservices.Config{
|
||
|
TailnetTarget: egressservices.TailnetTarget{IP: tailnetIPv4.String()},
|
||
|
Ports: ports,
|
||
|
}
|
||
|
fqdnSpec3 := egressservices.Config{
|
||
|
TailnetTarget: egressservices.TailnetTarget{IP: tailnetIPv4.String()},
|
||
|
Ports: ports2,
|
||
|
}
|
||
|
r := rule{containerPort: 4003, tailnetPort: 80, protocol: "tcp", tailnetIP: tailnetIPv4}
|
||
|
r1 := rule{containerPort: 4003, tailnetPort: 80, protocol: "tcp", tailnetIP: tailnetIPv6}
|
||
|
r2 := rule{tailnetPort: 53, containerPort: 4004, protocol: "udp", tailnetIP: tailnetIPv4}
|
||
|
r3 := rule{tailnetPort: 53, containerPort: 4004, protocol: "udp", tailnetIP: tailnetIPv6}
|
||
|
r4 := rule{containerPort: 4003, tailnetPort: 80, protocol: "tcp", tailnetIP: tailnetIPv4_1}
|
||
|
r5 := rule{containerPort: 4003, tailnetPort: 80, protocol: "tcp", tailnetIP: tailnetIPv6_1}
|
||
|
r6 := rule{containerPort: 4005, tailnetPort: 443, protocol: "tcp", tailnetIP: tailnetIPv4}
|
||
|
|
||
|
tests := []struct {
|
||
|
name string
|
||
|
svcName string
|
||
|
tailnetTargetIPs []netip.Addr
|
||
|
podIP string
|
||
|
spec egressservices.Config
|
||
|
status *egressservices.Status
|
||
|
wantRulesToAdd []rule
|
||
|
wantRulesToDelete []rule
|
||
|
}{
|
||
|
{
|
||
|
name: "add_fqdn_svc_that_does_not_yet_exist",
|
||
|
svcName: "test",
|
||
|
tailnetTargetIPs: []netip.Addr{tailnetIPv4, tailnetIPv6},
|
||
|
spec: fqdnSpec,
|
||
|
status: &egressservices.Status{},
|
||
|
wantRulesToAdd: []rule{r, r1},
|
||
|
wantRulesToDelete: []rule{},
|
||
|
},
|
||
|
{
|
||
|
name: "fqdn_svc_already_exists",
|
||
|
svcName: "test",
|
||
|
tailnetTargetIPs: []netip.Addr{tailnetIPv4, tailnetIPv6},
|
||
|
spec: fqdnSpec,
|
||
|
status: &egressservices.Status{
|
||
|
Services: map[string]*egressservices.ServiceStatus{"test": {
|
||
|
TailnetTargetIPs: []netip.Addr{tailnetIPv4, tailnetIPv6},
|
||
|
TailnetTarget: egressservices.TailnetTarget{FQDN: "test"},
|
||
|
Ports: ports,
|
||
|
}}},
|
||
|
wantRulesToAdd: []rule{},
|
||
|
wantRulesToDelete: []rule{},
|
||
|
},
|
||
|
{
|
||
|
name: "fqdn_svc_already_exists_add_port_remove_port",
|
||
|
svcName: "test",
|
||
|
tailnetTargetIPs: []netip.Addr{tailnetIPv4, tailnetIPv6},
|
||
|
spec: fqdnSpec1,
|
||
|
status: &egressservices.Status{
|
||
|
Services: map[string]*egressservices.ServiceStatus{"test": {
|
||
|
TailnetTargetIPs: []netip.Addr{tailnetIPv4, tailnetIPv6},
|
||
|
TailnetTarget: egressservices.TailnetTarget{FQDN: "test"},
|
||
|
Ports: ports,
|
||
|
}}},
|
||
|
wantRulesToAdd: []rule{r2, r3},
|
||
|
wantRulesToDelete: []rule{r, r1},
|
||
|
},
|
||
|
{
|
||
|
name: "fqdn_svc_already_exists_change_fqdn_backend_ips",
|
||
|
svcName: "test",
|
||
|
tailnetTargetIPs: []netip.Addr{tailnetIPv4_1, tailnetIPv6_1},
|
||
|
spec: fqdnSpec,
|
||
|
status: &egressservices.Status{
|
||
|
Services: map[string]*egressservices.ServiceStatus{"test": {
|
||
|
TailnetTargetIPs: []netip.Addr{tailnetIPv4, tailnetIPv6},
|
||
|
TailnetTarget: egressservices.TailnetTarget{FQDN: "test"},
|
||
|
Ports: ports,
|
||
|
}}},
|
||
|
wantRulesToAdd: []rule{r4, r5},
|
||
|
wantRulesToDelete: []rule{r, r1},
|
||
|
},
|
||
|
{
|
||
|
name: "add_ip_service",
|
||
|
svcName: "test",
|
||
|
tailnetTargetIPs: []netip.Addr{tailnetIPv4},
|
||
|
spec: fqdnSpec2,
|
||
|
status: &egressservices.Status{},
|
||
|
wantRulesToAdd: []rule{r},
|
||
|
wantRulesToDelete: []rule{},
|
||
|
},
|
||
|
{
|
||
|
name: "add_ip_service_already_exists",
|
||
|
svcName: "test",
|
||
|
tailnetTargetIPs: []netip.Addr{tailnetIPv4},
|
||
|
spec: fqdnSpec2,
|
||
|
status: &egressservices.Status{
|
||
|
Services: map[string]*egressservices.ServiceStatus{"test": {
|
||
|
TailnetTargetIPs: []netip.Addr{tailnetIPv4},
|
||
|
TailnetTarget: egressservices.TailnetTarget{IP: tailnetIPv4.String()},
|
||
|
Ports: ports,
|
||
|
}}},
|
||
|
wantRulesToAdd: []rule{},
|
||
|
wantRulesToDelete: []rule{},
|
||
|
},
|
||
|
{
|
||
|
name: "ip_service_add_port",
|
||
|
svcName: "test",
|
||
|
tailnetTargetIPs: []netip.Addr{tailnetIPv4},
|
||
|
spec: fqdnSpec3,
|
||
|
status: &egressservices.Status{
|
||
|
Services: map[string]*egressservices.ServiceStatus{"test": {
|
||
|
TailnetTargetIPs: []netip.Addr{tailnetIPv4},
|
||
|
TailnetTarget: egressservices.TailnetTarget{IP: tailnetIPv4.String()},
|
||
|
Ports: ports,
|
||
|
}}},
|
||
|
wantRulesToAdd: []rule{r6},
|
||
|
wantRulesToDelete: []rule{},
|
||
|
},
|
||
|
{
|
||
|
name: "ip_service_delete_port",
|
||
|
svcName: "test",
|
||
|
tailnetTargetIPs: []netip.Addr{tailnetIPv4},
|
||
|
spec: fqdnSpec,
|
||
|
status: &egressservices.Status{
|
||
|
Services: map[string]*egressservices.ServiceStatus{"test": {
|
||
|
TailnetTargetIPs: []netip.Addr{tailnetIPv4},
|
||
|
TailnetTarget: egressservices.TailnetTarget{IP: tailnetIPv4.String()},
|
||
|
Ports: ports2,
|
||
|
}}},
|
||
|
wantRulesToAdd: []rule{},
|
||
|
wantRulesToDelete: []rule{r6},
|
||
|
},
|
||
|
}
|
||
|
for _, tt := range tests {
|
||
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
gotRulesToAdd, gotRulesToDelete, err := updatesForCfg(tt.svcName, tt.spec, tt.status, tt.tailnetTargetIPs)
|
||
|
if err != nil {
|
||
|
t.Errorf("updatesForSvc() unexpected error %v", err)
|
||
|
return
|
||
|
}
|
||
|
if !reflect.DeepEqual(gotRulesToAdd, tt.wantRulesToAdd) {
|
||
|
t.Errorf("updatesForSvc() got rulesToAdd = \n%v\n want rulesToAdd \n%v", gotRulesToAdd, tt.wantRulesToAdd)
|
||
|
}
|
||
|
if !reflect.DeepEqual(gotRulesToDelete, tt.wantRulesToDelete) {
|
||
|
t.Errorf("updatesForSvc() got rulesToDelete = \n%v\n want rulesToDelete \n%v", gotRulesToDelete, tt.wantRulesToDelete)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|