| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- // 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)
- }
- })
- }
- }
|