Skip to content
This repository was archived by the owner on Nov 24, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- [#6021](https://github.com/apache/trafficcontrol/issues/6021) *Traffic Portal* Added the ability to view a change logs message in it's entirety by clicking on it.
- [#6033](https://github.com/apache/trafficcontrol/issues/6033) *Traffic Ops, Traffic Portal* Added ability to assign multiple server capabilities to a server.
- [#7032](https://github.com/apache/trafficcontrol/issues/7032) *Cache Config* Add t3c-apply flag to use local ATS version for config generation rather than Server package Parameter, to allow managing the ATS OS package via external tools. See 'man t3c-apply' and 'man t3c-generate' for details.
- [#7097](https://github.com/apache/trafficcontrol/issues/7097) *Traffic Ops, Traffic Portal* Added the `regional` field to Delivery Services, which indicates whether `maxOriginConnections` should be per Cache Group
- [#7097](https://github.com/apache/trafficcontrol/issues/7097) *Traffic Ops, Traffic Portal, t3c* Added the `regional` field to Delivery Services, which affects whether `maxOriginConnections` should be per Cache Group

### Changed
- [#7063](https://github.com/apache/trafficcontrol/pull/7063) *Traffic Ops* Python client now uses Traffic Ops API 4.1 by default.
Expand Down
10 changes: 8 additions & 2 deletions lib/go-atscfg/headerrewritedotconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ func getAssignedTierPeers(
dsRequiredCapabilities map[ServerCapability]struct{},
) ([]Server, []string) {
if ds.Topology != nil {
return getTopologyTierServers(dsRequiredCapabilities, tc.CacheGroupName(*server.Cachegroup), topology, cacheGroups, servers, serverCapabilities)
return getTopologyTierServers(ds, dsRequiredCapabilities, tc.CacheGroupName(*server.Cachegroup), topology, cacheGroups, servers, serverCapabilities)
}
if serverIsMid(server) {
return getAssignedMids(server, ds, servers, deliveryServiceServers, cacheGroups)
Expand Down Expand Up @@ -390,6 +390,9 @@ func getAssignedMids(
if tc.CacheStatus(*sv.Status) != tc.CacheStatusReported && tc.CacheStatus(*sv.Status) != tc.CacheStatusOnline {
continue
}
if ds != nil && ds.Regional && *sv.Cachegroup != *server.Cachegroup {
continue
}
serverCGs[tc.CacheGroupName(*sv.Cachegroup)] = struct{}{}
}

Expand Down Expand Up @@ -434,7 +437,7 @@ func getAssignedMids(
// This should only be used for DSes with Topologies.
// It returns all servers in with the Capabilities of ds in the same tier as cg.
// Returns the servers, and any warnings.
func getTopologyTierServers(dsRequiredCapabilities map[ServerCapability]struct{}, cg tc.CacheGroupName, topology tc.Topology, cacheGroups []tc.CacheGroupNullable, servers []Server, serverCapabilities map[int]map[ServerCapability]struct{}) ([]Server, []string) {
func getTopologyTierServers(ds *DeliveryService, dsRequiredCapabilities map[ServerCapability]struct{}, cg tc.CacheGroupName, topology tc.Topology, cacheGroups []tc.CacheGroupNullable, servers []Server, serverCapabilities map[int]map[ServerCapability]struct{}) ([]Server, []string) {
warnings := []string{}
topoServers := []Server{}
cacheGroupsInSameTier := getCachegroupsInSameTopologyTier(string(cg), cacheGroups, topology)
Expand All @@ -453,6 +456,9 @@ func getTopologyTierServers(dsRequiredCapabilities map[ServerCapability]struct{}
if !hasRequiredCapabilities(serverCapabilities[*sv.ID], dsRequiredCapabilities) {
continue
}
if ds != nil && ds.Regional && *sv.Cachegroup != string(cg) {
continue
}
topoServers = append(topoServers, sv)
}
return topoServers, warnings
Expand Down
232 changes: 232 additions & 0 deletions lib/go-atscfg/headerrewritedotconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,238 @@ func TestGetCachegroupsInSameTopologyTier(t *testing.T) {
}
}

func TestGetTopologyTierServers(t *testing.T) {
allCachegroups := []tc.CacheGroupNullable{
{
Name: util.StrPtr("edge1"),
Type: util.StrPtr(tc.CacheGroupEdgeTypeName),
},
{
Name: util.StrPtr("edge2"),
Type: util.StrPtr(tc.CacheGroupEdgeTypeName),
},
{
Name: util.StrPtr("org1"),
Type: util.StrPtr(tc.CacheGroupOriginTypeName),
},
}

allServers := []Server{
{
Cachegroup: util.Ptr("edge1"),
HostName: util.Ptr("edgeCache1"),
ID: util.Ptr(0),
},
{
Cachegroup: util.Ptr("edge2"),
HostName: util.Ptr("edgeCache2"),
ID: util.Ptr(0),
},
}

topology := tc.Topology{
Nodes: []tc.TopologyNode{
{
Cachegroup: "edge1",
Parents: []int{2},
},
{
Cachegroup: "edge2",
Parents: []int{2},
},
{
Cachegroup: "org1",
},
},
}

type testCase struct {
ds *DeliveryService
dsRequiredCapabilities map[ServerCapability]struct{}
cg tc.CacheGroupName
topology tc.Topology
cacheGroups []tc.CacheGroupNullable
servers []Server
serverCapabilities map[int]map[ServerCapability]struct{}

expectedHostnames []string
}
testCases := []testCase{
{
ds: &DeliveryService{},
cg: tc.CacheGroupName("edge1"),
topology: topology,
cacheGroups: allCachegroups,
servers: allServers,

expectedHostnames: []string{"edgeCache1", "edgeCache2"},
},
{
ds: &DeliveryService{Regional: true},
cg: tc.CacheGroupName("edge1"),
topology: topology,
cacheGroups: allCachegroups,
servers: allServers,

expectedHostnames: []string{"edgeCache1"},
},
}

for _, tc := range testCases {
actualServers, _ := getTopologyTierServers(tc.ds, tc.dsRequiredCapabilities, tc.cg, tc.topology, tc.cacheGroups, tc.servers, tc.serverCapabilities)
actualHostnames := []string{}
for _, as := range actualServers {
actualHostnames = append(actualHostnames, *as.HostName)
}
if !reflect.DeepEqual(tc.expectedHostnames, actualHostnames) {
t.Errorf("getting servers in same topology tier -- expected: %v, actual: %v", tc.expectedHostnames, actualHostnames)
}
}
}

func TestGetAssignedMids(t *testing.T) {
allCachegroups := []tc.CacheGroupNullable{
{
Name: util.StrPtr("edge1"),
ParentName: util.Ptr("mid1"),
Type: util.StrPtr(tc.CacheGroupEdgeTypeName),
},
{
Name: util.StrPtr("edge2"),
ParentName: util.Ptr("mid2"),
Type: util.StrPtr(tc.CacheGroupEdgeTypeName),
},
{
Name: util.StrPtr("mid1"),
ParentName: util.Ptr("org1"),
Type: util.StrPtr(tc.CacheGroupMidTypeName),
},
{
Name: util.StrPtr("mid2"),
ParentName: util.Ptr("org1"),
Type: util.StrPtr(tc.CacheGroupMidTypeName),
},
{
Name: util.StrPtr("org1"),
Type: util.StrPtr(tc.CacheGroupOriginTypeName),
},
}

allServers := []Server{
{
Cachegroup: util.Ptr("edge1"),
CDNName: util.Ptr("mycdn"),
HostName: util.Ptr("edgeCache1"),
ID: util.Ptr(1),
Status: util.Ptr(string(tc.CacheStatusReported)),
},
{
Cachegroup: util.Ptr("edge2"),
CDNName: util.Ptr("mycdn"),
HostName: util.Ptr("edgeCache2"),
ID: util.Ptr(2),
Status: util.Ptr(string(tc.CacheStatusReported)),
},

{
Cachegroup: util.Ptr("mid1"),
CDNName: util.Ptr("mycdn"),
HostName: util.Ptr("midCache1"),
ID: util.Ptr(3),
Status: util.Ptr(string(tc.CacheStatusReported)),
},
{
Cachegroup: util.Ptr("mid2"),
CDNName: util.Ptr("mycdn"),
HostName: util.Ptr("midCache2"),
ID: util.Ptr(4),
Status: util.Ptr(string(tc.CacheStatusReported)),
},
}

allDeliveryServices := []DeliveryService{{}, {}}
allDeliveryServices[0].ID = util.Ptr(1)
allDeliveryServices[0].CDNName = util.Ptr("mycdn")
allDeliveryServices[1].ID = util.Ptr(2)
allDeliveryServices[1].Regional = true
allDeliveryServices[1].CDNName = util.Ptr("mycdn")

type testCase struct {
server *Server
ds *DeliveryService
deliveryServiceServers []DeliveryServiceServer
servers []Server
cacheGroups []tc.CacheGroupNullable

expectedHostnames []string
}
testCases := []testCase{
{
server: &allServers[0],
ds: &allDeliveryServices[0],
servers: allServers,
deliveryServiceServers: []DeliveryServiceServer{
{
Server: 1,
DeliveryService: 1,
},
{
Server: 2,
DeliveryService: 1,
},
{
Server: 3,
DeliveryService: 1,
},
{
Server: 4,
DeliveryService: 1,
},
},
cacheGroups: allCachegroups,

expectedHostnames: []string{"midCache1", "midCache2"},
},
{
server: &allServers[0],
ds: &allDeliveryServices[1],
servers: allServers,
deliveryServiceServers: []DeliveryServiceServer{
{
Server: 1,
DeliveryService: 2,
},
{
Server: 2,
DeliveryService: 2,
},
{
Server: 3,
DeliveryService: 2,
},
{
Server: 4,
DeliveryService: 2,
},
},
cacheGroups: allCachegroups,

expectedHostnames: []string{"midCache1"},
},
}

for _, tc := range testCases {
actualServers, _ := getAssignedMids(tc.server, tc.ds, tc.servers, tc.deliveryServiceServers, tc.cacheGroups)
actualHostnames := []string{}
for _, as := range actualServers {
actualHostnames = append(actualHostnames, *as.HostName)
}
if !reflect.DeepEqual(tc.expectedHostnames, actualHostnames) {
t.Errorf("getting servers in same cachegroup tier -- expected: %v, actual: %v", tc.expectedHostnames, actualHostnames)
}
}
}

func TestMakeHeaderRewriteMidDotConfig(t *testing.T) {
cdnName := "mycdn"
hdr := "myHeaderComment"
Expand Down
4 changes: 4 additions & 0 deletions lib/go-util/ptr.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ package util

import "time"

func Ptr[T any](v T) *T {
return &v
}

func StrPtr(str string) *string {
return &str
}
Expand Down
6 changes: 6 additions & 0 deletions lib/go-util/ptr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ package util

import "fmt"

func ExamplePtr() {
ptr := Ptr("testquest")
fmt.Println(*ptr)
// Output: testquest
}

func ExampleStrPtr() {
ptr := StrPtr("testquest")
fmt.Println(*ptr)
Expand Down