From 26b62dd74c69fc7514f206e2bcd9b8de913e0058 Mon Sep 17 00:00:00 2001 From: jpappa200 Date: Thu, 17 Mar 2022 23:10:00 -0400 Subject: [PATCH 1/5] If there are no parents use secondary parents if configured. --- lib/go-atscfg/parentdotconfig.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/go-atscfg/parentdotconfig.go b/lib/go-atscfg/parentdotconfig.go index 74341117e8..dba58fe31a 100644 --- a/lib/go-atscfg/parentdotconfig.go +++ b/lib/go-atscfg/parentdotconfig.go @@ -970,7 +970,13 @@ func getTopologyParentConfigLine( return nil, warnings, errors.New("getting topology parents for '" + *ds.XMLID + "': skipping! " + err.Error()) } if len(parents) == 0 { - return nil, warnings, errors.New("getting topology parents for '" + *ds.XMLID + "': no parents found! skipping! (Does your Topology have a CacheGroup with no servers in it?)") + if len(secondaryParents) > 0 { + warnings = append(warnings, "getting topology parents for '"+*ds.XMLID+"': no parents found! using secondary parents") + parents = secondaryParents + secondaryParents = nil + } else { + return nil, warnings, errors.New("getting topology parents for '" + *ds.XMLID + "': no parents found! skipping! (Does your Topology have a CacheGroup with no servers in it?)") + } } txt.Parents = parents From 043da31962f45a5ddb26e7aea494cb1e1bde5361 Mon Sep 17 00:00:00 2001 From: jpappa200 Date: Thu, 17 Mar 2022 23:10:00 -0400 Subject: [PATCH 2/5] If there are no parents use secondary parents if configured. --- lib/go-atscfg/parentdotconfig.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/go-atscfg/parentdotconfig.go b/lib/go-atscfg/parentdotconfig.go index 74341117e8..dba58fe31a 100644 --- a/lib/go-atscfg/parentdotconfig.go +++ b/lib/go-atscfg/parentdotconfig.go @@ -970,7 +970,13 @@ func getTopologyParentConfigLine( return nil, warnings, errors.New("getting topology parents for '" + *ds.XMLID + "': skipping! " + err.Error()) } if len(parents) == 0 { - return nil, warnings, errors.New("getting topology parents for '" + *ds.XMLID + "': no parents found! skipping! (Does your Topology have a CacheGroup with no servers in it?)") + if len(secondaryParents) > 0 { + warnings = append(warnings, "getting topology parents for '"+*ds.XMLID+"': no parents found! using secondary parents") + parents = secondaryParents + secondaryParents = nil + } else { + return nil, warnings, errors.New("getting topology parents for '" + *ds.XMLID + "': no parents found! skipping! (Does your Topology have a CacheGroup with no servers in it?)") + } } txt.Parents = parents From 26aea6b8db19046ac8b00440afeac1adf0722aaf Mon Sep 17 00:00:00 2001 From: jpappa200 Date: Mon, 25 Apr 2022 16:46:07 -0400 Subject: [PATCH 3/5] added 2 tests to use secondary parents when no primary parents are available. --- lib/go-atscfg/parentdotconfig_test.go | 263 ++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) diff --git a/lib/go-atscfg/parentdotconfig_test.go b/lib/go-atscfg/parentdotconfig_test.go index 628b973cbd..ed1cb03906 100644 --- a/lib/go-atscfg/parentdotconfig_test.go +++ b/lib/go-atscfg/parentdotconfig_test.go @@ -404,6 +404,122 @@ func TestMakeParentDotConfigMSOSecondaryParent(t *testing.T) { } } +func TestMakeParentDotConfigMSONoPrimaryParent(t *testing.T) { + hdr := &ParentConfigOpts{AddComments: false, HdrComment: "myHeaderComment"} + + ds0 := makeParentDS() + ds0Type := tc.DSTypeHTTP + ds0.Type = &ds0Type + ds0.QStringIgnore = util.IntPtr(int(tc.QStringIgnoreUseInCacheKeyAndPassUp)) + ds0.OrgServerFQDN = util.StrPtr("http://ds0.example.net") + ds0.MultiSiteOrigin = util.BoolPtr(true) + dses := []DeliveryService{*ds0} + + 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() + + mid0 := makeTestParentServer() + mid0.Cachegroup = util.StrPtr("midCG0") + mid0.CachegroupID = util.IntPtr(500) + mid0.HostName = util.StrPtr("my-parent-0") + mid0.DomainName = util.StrPtr("my-parent-0-domain") + mid0.Status = util.StrPtr("ADMIN_DOWN") + mid0.ID = util.IntPtr(45) + setIP(mid0, "192.168.2.2") + + mid1 := makeTestParentServer() + mid1.Cachegroup = util.StrPtr("midCG1") + mid1.CachegroupID = util.IntPtr(501) + mid1.HostName = util.StrPtr("my-parent-1") + mid1.DomainName = util.StrPtr("my-parent-1-domain") + mid1.ID = util.IntPtr(46) + setIP(mid1, "192.168.2.3") + + servers := []Server{*server, *mid0, *mid1} + + topologies := []tc.Topology{} + serverCapabilities := map[int]map[ServerCapability]struct{}{} + dsRequiredCapabilities := map[int]map[ServerCapability]struct{}{} + + eCG := &tc.CacheGroupNullable{} + eCG.Name = server.Cachegroup + eCG.ID = server.CachegroupID + eCG.ParentName = mid0.Cachegroup + eCG.ParentCachegroupID = mid0.CachegroupID + eCG.SecondaryParentName = mid1.Cachegroup + eCG.SecondaryParentCachegroupID = mid1.CachegroupID + eCGType := tc.CacheGroupEdgeTypeName + eCG.Type = &eCGType + + mCG := &tc.CacheGroupNullable{} + mCG.Name = mid0.Cachegroup + mCG.ID = mid0.CachegroupID + mCGType := tc.CacheGroupMidTypeName + mCG.Type = &mCGType + + mCG1 := &tc.CacheGroupNullable{} + mCG1.Name = mid1.Cachegroup + mCG1.ID = mid1.CachegroupID + mCGType1 := tc.CacheGroupMidTypeName + mCG1.Type = &mCGType1 + + cgs := []tc.CacheGroupNullable{*eCG, *mCG, *mCG1} + + dss := []DeliveryServiceServer{ + DeliveryServiceServer{ + Server: *server.ID, + DeliveryService: *ds0.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.HdrComment) + + txtx := strings.Replace(txt, " ", "", -1) + + if !strings.Contains(txtx, `parent="my-parent-1.my-parent-1-domain:80|0.999`) { + t.Errorf("expected primary parent 'my-parent-1.my-parent-1-domain', actual: '%v'", txt) + } +} + func TestMakeParentDotConfigTopologies(t *testing.T) { hdr := &ParentConfigOpts{AddComments: false, HdrComment: "myHeaderComment"} @@ -2932,6 +3048,153 @@ func TestMakeParentDotConfigHTTPSOriginTopology(t *testing.T) { } } +func TestMakeParentDotConfigHTTPSOriginTopologyNoPrimaryParent(t *testing.T) { + hdr := &ParentConfigOpts{AddComments: true, HdrComment: "myHeaderComment"} + + ds0 := makeParentDS() + ds0Type := tc.DSTypeHTTP + ds0.Type = &ds0Type + ds0.QStringIgnore = util.IntPtr(int(tc.QStringIgnoreUseInCacheKeyAndPassUp)) + ds0.OrgServerFQDN = util.StrPtr("https://ds0.example.net") + ds0.ProfileID = util.IntPtr(311) + ds0.ProfileName = util.StrPtr("ds0Profile") + + 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.ProfileID = util.IntPtr(312) + ds1.ProfileName = util.StrPtr("ds1Profile") + + dses := []DeliveryService{*ds0, *ds1} + + parentConfigParams := []tc.Parameter{ + { + Name: ParentConfigParamQStringHandling, + ConfigFile: "parent.config", + Value: "myQStringHandlingParam", + Profiles: []byte(`["serverprofile"]`), + }, + { + Name: ParentConfigParamAlgorithm, + ConfigFile: "parent.config", + Value: tc.AlgorithmConsistentHash, + Profiles: []byte(`["serverprofile"]`), + }, + { + Name: ParentConfigParamQString, + ConfigFile: "parent.config", + Value: "myQstringParam", + Profiles: []byte(`["serverprofile"]`), + }, + } + + serverParams := []tc.Parameter{ + { + Name: "trafficserver", + ConfigFile: "package", + Value: "8", + Profiles: []byte(`["global"]`), + }, + } + + server := makeTestParentServer() + server.Cachegroup = util.StrPtr("edgeCG") + server.CachegroupID = util.IntPtr(400) + + mid0 := makeTestParentServer() + mid0.Cachegroup = util.StrPtr("midCG") + mid0.CachegroupID = util.IntPtr(500) + mid0.HostName = util.StrPtr("mymid") + mid0.ID = util.IntPtr(45) + mid0.Status = util.StrPtr("ADMIN_DOWN") + setIP(mid0, "192.168.2.2") + + mid1 := makeTestParentServer() + mid1.Cachegroup = util.StrPtr("midCG2") + mid1.CachegroupID = util.IntPtr(501) + mid1.HostName = util.StrPtr("mymid1") + mid1.ID = util.IntPtr(46) + setIP(mid1, "192.168.2.3") + + servers := []Server{*server, *mid0, *mid1} + + topologies := []tc.Topology{ + { + Name: "t0", + Nodes: []tc.TopologyNode{ + { + Cachegroup: "edgeCG", + Parents: []int{1, 2}, + }, + { + Cachegroup: "midCG", + }, + { + Cachegroup: "midCG2", + }, + }, + }, + } + + serverCapabilities := map[int]map[ServerCapability]struct{}{} + dsRequiredCapabilities := map[int]map[ServerCapability]struct{}{} + + eCG := &tc.CacheGroupNullable{} + eCG.Name = server.Cachegroup + eCG.ID = server.CachegroupID + eCG.ParentName = mid0.Cachegroup + eCG.ParentCachegroupID = mid0.CachegroupID + eCG.SecondaryParentName = mid1.Cachegroup + eCG.SecondaryParentCachegroupID = mid1.CachegroupID + eCGType := tc.CacheGroupEdgeTypeName + eCG.Type = &eCGType + + mCG := &tc.CacheGroupNullable{} + mCG.Name = mid0.Cachegroup + mCG.ID = mid0.CachegroupID + mCGType := tc.CacheGroupMidTypeName + mCG.Type = &mCGType + + mCG2 := &tc.CacheGroupNullable{} + mCG2.Name = mid1.Cachegroup + mCG2.ID = mid1.CachegroupID + mCGType2 := tc.CacheGroupMidTypeName + mCG2.Type = &mCGType2 + + cgs := []tc.CacheGroupNullable{*eCG, *mCG, *mCG2} + + dss := []DeliveryServiceServer{ + { + Server: *server.ID, + DeliveryService: *ds0.ID, + }, + { + Server: *server.ID, + DeliveryService: *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.HdrComment) + + if !strings.Contains(txt, `parent="mymid1.mydomain.example.net:80|0.999"`) { + t.Errorf("expected topology parent.config withparent=\"mymid1.mydomain.example.net:80|0.999\", actual: '%v'", txt) + } +} + func TestMakeParentDotConfigMergeParentGroupTopology(t *testing.T) { hdr := &ParentConfigOpts{AddComments: true, HdrComment: "myHeaderComment"} From 1738673a79cece26fd73427f6f9c624f005eb508 Mon Sep 17 00:00:00 2001 From: jpappa200 Date: Mon, 25 Apr 2022 17:02:39 -0400 Subject: [PATCH 4/5] Substituted admin_down with constant tc.CacheStatusAdminDown --- lib/go-atscfg/parentdotconfig_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/go-atscfg/parentdotconfig_test.go b/lib/go-atscfg/parentdotconfig_test.go index ed1cb03906..3710c97521 100644 --- a/lib/go-atscfg/parentdotconfig_test.go +++ b/lib/go-atscfg/parentdotconfig_test.go @@ -452,7 +452,7 @@ func TestMakeParentDotConfigMSONoPrimaryParent(t *testing.T) { mid0.CachegroupID = util.IntPtr(500) mid0.HostName = util.StrPtr("my-parent-0") mid0.DomainName = util.StrPtr("my-parent-0-domain") - mid0.Status = util.StrPtr("ADMIN_DOWN") + mid0.Status = util.StrPtr(string(tc.CacheStatusAdminDown)) mid0.ID = util.IntPtr(45) setIP(mid0, "192.168.2.2") @@ -3110,7 +3110,7 @@ func TestMakeParentDotConfigHTTPSOriginTopologyNoPrimaryParent(t *testing.T) { mid0.CachegroupID = util.IntPtr(500) mid0.HostName = util.StrPtr("mymid") mid0.ID = util.IntPtr(45) - mid0.Status = util.StrPtr("ADMIN_DOWN") + mid0.Status = util.StrPtr(string(tc.CacheStatusAdminDown)) setIP(mid0, "192.168.2.2") mid1 := makeTestParentServer() From b0ea90ffed570a902a06e98c4b557ff12496faf5 Mon Sep 17 00:00:00 2001 From: jpappa200 Date: Mon, 25 Apr 2022 17:29:17 -0400 Subject: [PATCH 5/5] Added changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ac6841b14..af3a862e14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Fixed searching of the ds parameter merge_parent_groups slice. - Fixed TO API `PUT /servers/:id/status` to only queue updates on the same CDN as the updated server - t3c-generate fix for combining remapconfig and cachekeyconfig parameters for MakeRemapDotConfig call. +- [#6780](https://github.com/apache/trafficcontrol/issues/6780) Fixed t3c to use secondary parents when there are no primary parents available. ### Removed - Remove traffic\_portal dependencies to mitigate `npm audit` issues, specifically `grunt-concurrent`, `grunt-contrib-concat`, `grunt-contrib-cssmin`, `grunt-contrib-jsmin`, `grunt-contrib-uglify`, `grunt-contrib-htmlmin`, `grunt-newer`, and `grunt-wiredep`