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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- [#5195](https://github.com/apache/trafficcontrol/issues/5195) - Correctly show CDN ID in Changelog during Snap
- Fixed Traffic Router logging unnecessary warnings for IPv6-only caches
- Fixed parent.config generation for topology-based delivery services (inline comments not supported)
- Fixed parent.config generation for MSO delivery services with required capabilities
- [#5294](https://github.com/apache/trafficcontrol/issues/5294) - TP ag grid tables now properly persist column filters
on page refresh.
- [#5295](https://github.com/apache/trafficcontrol/issues/5295) - TP types/servers table now clears all filters instead
Expand Down
20 changes: 5 additions & 15 deletions lib/go-atscfg/parentdotconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ func MakeParentDotConfig(
parentServerDSes[*dss.Server][*dss.DeliveryService] = struct{}{}
}

originServers, profileCaches, orgProfWarns, err := getOriginServersAndProfileCaches(cgServers, parentServerDSes, profileParentConfigParams, dses, serverCapabilities, dsRequiredCapabilities)
originServers, profileCaches, orgProfWarns, err := getOriginServersAndProfileCaches(cgServers, parentServerDSes, profileParentConfigParams, dses, serverCapabilities)
warnings = append(warnings, orgProfWarns...)
if err != nil {
return Cfg{}, makeErr(warnings, "getting origin servers and profile caches: "+err.Error())
Expand Down Expand Up @@ -341,7 +341,7 @@ func MakeParentDotConfig(
warnings = append(warnings, "delivery service "+*ds.XMLID+" has no parent servers")
}

parents, secondaryParents, parentWarns := getMSOParentStrs(&ds, parentInfos[OriginHost(orgURI.Hostname())], atsMajorVer, dsRequiredCapabilities, dsParams.Algorithm, dsParams.TryAllPrimariesBeforeSecondary)
parents, secondaryParents, parentWarns := getMSOParentStrs(&ds, parentInfos[OriginHost(orgURI.Hostname())], atsMajorVer, dsParams.Algorithm, dsParams.TryAllPrimariesBeforeSecondary)
warnings = append(warnings, parentWarns...)
textLine += parents + secondaryParents + ` round_robin=` + dsParams.Algorithm + ` qstring=` + parentQStr + ` go_direct=false parent_is_proxy=false`
textLine += getParentRetryStr(true, atsMajorVer, dsParams.ParentRetry, dsParams.UnavailableServerRetryResponses, dsParams.MaxSimpleRetries, dsParams.MaxUnavailableServerRetries)
Expand Down Expand Up @@ -1029,7 +1029,7 @@ func getTopologyParents(
continue
}

if !hasRequiredCapabilities(serverCapabilities[*sv.ID], dsRequiredCapabilities[*ds.ID]) {
if sv.Type != tc.OriginTypeName && !hasRequiredCapabilities(serverCapabilities[*sv.ID], dsRequiredCapabilities[*ds.ID]) {
continue
}
if *sv.Cachegroup == parentCG {
Expand Down Expand Up @@ -1136,7 +1136,6 @@ func getMSOParentStrs(
ds *DeliveryService,
parentInfos []parentInfo,
atsMajorVer int,
dsRequiredCapabilities map[int]map[ServerCapability]struct{},
msoAlgorithm string,
tryAllPrimariesBeforeSecondary bool,
) (string, string, []string) {
Expand All @@ -1150,10 +1149,6 @@ func getMSOParentStrs(
secondaryParentInfo := []string{}
nullParentInfo := []string{}
for _, parent := range ([]parentInfo)(rankedParents) {
if !hasRequiredCapabilities(parent.Capabilities, dsRequiredCapabilities[*ds.ID]) {
continue
}

if parent.PrimaryParent {
parentInfoTxt = append(parentInfoTxt, parent.Format())
} else if parent.SecondaryParent {
Expand Down Expand Up @@ -1263,7 +1258,6 @@ func getOriginServersAndProfileCaches(
profileParentConfigParams map[string]map[string]string, // map[profileName][paramName]paramVal
dses []DeliveryService,
serverCapabilities map[int]map[ServerCapability]struct{},
dsRequiredCapabilities map[int]map[ServerCapability]struct{},
) (map[OriginHost][]cgServer, map[ProfileID]profileCache, []string, error) {
warnings := []string{}
originServers := map[OriginHost][]cgServer{} // "deliveryServices" in Perl
Expand Down Expand Up @@ -1363,12 +1357,8 @@ func getOriginServersAndProfileCaches(
// warnings = append(warnings, fmt.Sprintf(("ds %v has no origins! Skipping!\n", dsID) // TODO determine if this is normal
continue
}
if hasRequiredCapabilities(serverCapabilities[*cgSv.ID], dsRequiredCapabilities[dsID]) {
orgHost := OriginHost(orgURI.Host)
originServers[orgHost] = append(originServers[orgHost], realCGServer)
} else {
warnings = append(warnings, fmt.Sprintf("ds %v server %v missing required caps, skipping!\n", dsID, orgURI.Host))
}
orgHost := OriginHost(orgURI.Host)
originServers[orgHost] = append(originServers[orgHost], realCGServer)
}
} else {
originServers[deliveryServicesAllParentsKey] = append(originServers[deliveryServicesAllParentsKey], realCGServer)
Expand Down
268 changes: 268 additions & 0 deletions lib/go-atscfg/parentdotconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1253,6 +1253,274 @@ func TestMakeParentDotConfigTopologiesMSO(t *testing.T) {
}
}

func TestMakeParentDotConfigTopologiesMSOWithCapabilities(t *testing.T) {
hdr := "myHeaderComment"

ds1 := makeParentDS()
ds1.ID = util.IntPtr(43)
ds1Type := tc.DSTypeDNS
ds1.Type = &ds1Type
ds1.QStringIgnore = util.IntPtr(int(tc.QStringIgnoreDrop))
ds1.OrgServerFQDN = util.StrPtr("http://ds1.example.net")
ds1.Topology = util.StrPtr("t0")
ds1.MultiSiteOrigin = util.BoolPtr(true)

dses := []DeliveryService{*ds1}

parentConfigParams := []tc.Parameter{
tc.Parameter{
Name: ParentConfigParamQStringHandling,
ConfigFile: "parent.config",
Value: "myQStringHandlingParam",
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
Name: ParentConfigParamAlgorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
Name: ParentConfigParamQString,
ConfigFile: "parent.config",
Value: "myQstringParam",
Profiles: []byte(`["serverprofile"]`),
},
}

serverParams := []tc.Parameter{
tc.Parameter{
Name: "trafficserver",
ConfigFile: "package",
Value: "7",
Profiles: []byte(`["global"]`),
},
}

server := makeTestParentServer()
server.Cachegroup = util.StrPtr("edgeCG")
server.CachegroupID = util.IntPtr(400)
server.ID = util.IntPtr(44)

origin0 := makeTestParentServer()
origin0.Cachegroup = util.StrPtr("originCG")
origin0.CachegroupID = util.IntPtr(500)
origin0.HostName = util.StrPtr("myorigin0")
origin0.ID = util.IntPtr(45)
setIP(origin0, "192.168.2.2")
origin0.Type = tc.OriginTypeName
origin0.TypeID = util.IntPtr(991)

origin1 := makeTestParentServer()
origin1.Cachegroup = util.StrPtr("originCG")
origin1.CachegroupID = util.IntPtr(500)
origin1.HostName = util.StrPtr("myorigin1")
origin1.ID = util.IntPtr(46)
setIP(origin1, "192.168.2.3")
origin1.Type = tc.OriginTypeName
origin1.TypeID = util.IntPtr(991)

servers := []Server{*server, *origin0, *origin1}

topologies := []tc.Topology{
tc.Topology{
Name: "t0",
Nodes: []tc.TopologyNode{
tc.TopologyNode{
Cachegroup: "edgeCG",
Parents: []int{1},
},
tc.TopologyNode{
Cachegroup: "originCG",
},
},
},
}

serverCapabilities := map[int]map[ServerCapability]struct{}{
*server.ID: {
ServerCapability("FOO"): struct{}{},
},
}
dsRequiredCapabilities := map[int]map[ServerCapability]struct{}{
*ds1.ID: {
ServerCapability("FOO"): struct{}{},
},
}

eCG := &tc.CacheGroupNullable{}
eCG.Name = server.Cachegroup
eCG.ID = server.CachegroupID
eCG.ParentName = origin0.Cachegroup
eCG.ParentCachegroupID = origin0.CachegroupID
eCGType := tc.CacheGroupEdgeTypeName
eCG.Type = &eCGType

oCG := &tc.CacheGroupNullable{}
oCG.Name = origin0.Cachegroup
oCG.ID = origin0.CachegroupID
oCGType := tc.CacheGroupOriginTypeName
oCG.Type = &oCGType

cgs := []tc.CacheGroupNullable{*eCG, *oCG}

dss := []tc.DeliveryServiceServer{
tc.DeliveryServiceServer{
Server: util.IntPtr(*origin0.ID),
DeliveryService: util.IntPtr(*ds1.ID),
},
}
cdn := &tc.CDN{
DomainName: "cdndomain.example",
Name: "my-cdn-name",
}

cfg, err := MakeParentDotConfig(dses, server, servers, topologies, serverParams, parentConfigParams, serverCapabilities, dsRequiredCapabilities, cgs, dss, cdn, hdr)
if err != nil {
t.Fatal(err)
}
txt := cfg.Text

testComment(t, txt, hdr)

if !strings.Contains(txt, "dest_domain=ds1.example.net") {
t.Errorf("expected parent 'dest_domain=ds1.example.net', actual: '%v'", txt)
}
if !strings.Contains(txt, "myorigin0") {
t.Errorf("expected origin0 with DeliveryServiceServer assigned to this DS, actual: '%v'", txt)
}
if strings.Contains(txt, "myorigin1") {
t.Errorf("expected no origin1 without DeliveryServiceServer assigned to this DS, actual: '%v'", txt)
}
}

func TestMakeParentDotConfigMSOWithCapabilities(t *testing.T) {
hdr := "myHeaderComment"

ds1 := makeParentDS()
ds1.ID = util.IntPtr(43)
ds1Type := tc.DSTypeDNS
ds1.Type = &ds1Type
ds1.QStringIgnore = util.IntPtr(int(tc.QStringIgnoreDrop))
ds1.OrgServerFQDN = util.StrPtr("http://ds1.example.net")
ds1.MultiSiteOrigin = util.BoolPtr(true)

dses := []DeliveryService{*ds1}

parentConfigParams := []tc.Parameter{
tc.Parameter{
Name: ParentConfigParamQStringHandling,
ConfigFile: "parent.config",
Value: "myQStringHandlingParam",
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
Name: ParentConfigParamAlgorithm,
ConfigFile: "parent.config",
Value: tc.AlgorithmConsistentHash,
Profiles: []byte(`["serverprofile"]`),
},
tc.Parameter{
Name: ParentConfigParamQString,
ConfigFile: "parent.config",
Value: "myQstringParam",
Profiles: []byte(`["serverprofile"]`),
},
}

serverParams := []tc.Parameter{
tc.Parameter{
Name: "trafficserver",
ConfigFile: "package",
Value: "7",
Profiles: []byte(`["global"]`),
},
}

server := makeTestParentServer()
server.Cachegroup = util.StrPtr("midCG")
server.Type = "MID"
server.CachegroupID = util.IntPtr(400)
server.ID = util.IntPtr(44)

origin0 := makeTestParentServer()
origin0.Cachegroup = util.StrPtr("originCG")
origin0.CachegroupID = util.IntPtr(500)
origin0.HostName = util.StrPtr("myorigin0")
origin0.ID = util.IntPtr(45)
setIP(origin0, "192.168.2.2")
origin0.Type = tc.OriginTypeName
origin0.TypeID = util.IntPtr(991)

origin1 := makeTestParentServer()
origin1.Cachegroup = util.StrPtr("originCG")
origin1.CachegroupID = util.IntPtr(500)
origin1.HostName = util.StrPtr("myorigin1")
origin1.ID = util.IntPtr(46)
setIP(origin1, "192.168.2.3")
origin1.Type = tc.OriginTypeName
origin1.TypeID = util.IntPtr(991)

servers := []Server{*server, *origin0, *origin1}

serverCapabilities := map[int]map[ServerCapability]struct{}{
*server.ID: {
ServerCapability("FOO"): struct{}{},
},
}
dsRequiredCapabilities := map[int]map[ServerCapability]struct{}{
*ds1.ID: {
ServerCapability("FOO"): struct{}{},
},
}

midCG := &tc.CacheGroupNullable{}
midCG.Name = server.Cachegroup
midCG.ID = server.CachegroupID
midCG.ParentName = origin0.Cachegroup
midCG.ParentCachegroupID = origin0.CachegroupID
midCGType := tc.CacheGroupMidTypeName
midCG.Type = &midCGType

oCG := &tc.CacheGroupNullable{}
oCG.Name = origin0.Cachegroup
oCG.ID = origin0.CachegroupID
oCGType := tc.CacheGroupOriginTypeName
oCG.Type = &oCGType

cgs := []tc.CacheGroupNullable{*midCG, *oCG}

dss := []tc.DeliveryServiceServer{
tc.DeliveryServiceServer{
Server: util.IntPtr(*origin0.ID),
DeliveryService: util.IntPtr(*ds1.ID),
},
}
cdn := &tc.CDN{
DomainName: "cdndomain.example",
Name: "my-cdn-name",
}
topologies := []tc.Topology{}

cfg, err := MakeParentDotConfig(dses, server, servers, topologies, serverParams, parentConfigParams, serverCapabilities, dsRequiredCapabilities, cgs, dss, cdn, hdr)
if err != nil {
t.Fatal(err)
}
txt := cfg.Text

testComment(t, txt, hdr)

if !strings.Contains(txt, "dest_domain=ds1.example.net") {
t.Errorf("expected parent 'dest_domain=ds1.example.net', actual: '%v'", txt)
}
if !strings.Contains(txt, "myorigin0") {
t.Errorf("expected origin0 with DeliveryServiceServer assigned to this DS, actual: '%v'", txt)
}
if strings.Contains(txt, "myorigin1") {
t.Errorf("expected no origin1 without DeliveryServiceServer assigned to this DS, actual: '%v'", txt)
}
}

func TestMakeParentDotConfigTopologiesMSOParams(t *testing.T) {
hdr := "myHeaderComment"

Expand Down