You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by oc...@apache.org on 2021/01/13 16:12:01 UTC

[trafficcontrol] branch 5.0.x updated (cc92181 -> e07f6a1)

This is an automated email from the ASF dual-hosted git repository.

ocket8888 pushed a change to branch 5.0.x
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git.


    from cc92181  Limit which Topology parent CacheGroup Servers to check for updates (#5416)
     new a2ee75c  Add atscfg parent.config topology comment (#5414)
     new 008d26c  Ignore parent upd_pending for parent ORG_LOC-type Cache Groups (#5425)
     new e07f6a1  Remove debug print (#5429)

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 lib/go-atscfg/headerrewritemiddotconfig.go         |   2 -
 lib/go-atscfg/parentdotconfig.go                   |  50 ++-
 lib/go-atscfg/parentdotconfig_test.go              | 346 +++++++++++++++++++--
 .../testing/api/v3/serverupdatestatus_test.go      |   4 +
 traffic_ops/testing/api/v3/tc-fixtures.json        |   3 +-
 .../server/servers_update_status.go                |   2 +
 traffic_ops_ort/atstccfg/cfgfile/wrappers.go       |   5 +-
 7 files changed, 373 insertions(+), 39 deletions(-)


[trafficcontrol] 02/03: Ignore parent upd_pending for parent ORG_LOC-type Cache Groups (#5425)

Posted by oc...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ocket8888 pushed a commit to branch 5.0.x
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git

commit 008d26c001a80329f506d8e6808b187393767cc2
Author: Zach Hoffman <zr...@apache.org>
AuthorDate: Wed Jan 13 08:58:25 2021 -0700

    Ignore parent upd_pending for parent ORG_LOC-type Cache Groups (#5425)
    
    (cherry picked from commit e779b4030acab6b924cc4f17cc76642dcea32e49)
---
 traffic_ops/testing/api/v3/serverupdatestatus_test.go          | 4 ++++
 traffic_ops/testing/api/v3/tc-fixtures.json                    | 3 ++-
 traffic_ops/traffic_ops_golang/server/servers_update_status.go | 2 ++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/traffic_ops/testing/api/v3/serverupdatestatus_test.go b/traffic_ops/testing/api/v3/serverupdatestatus_test.go
index 0682d85..7483e7f 100644
--- a/traffic_ops/testing/api/v3/serverupdatestatus_test.go
+++ b/traffic_ops/testing/api/v3/serverupdatestatus_test.go
@@ -474,6 +474,10 @@ func TestSetTopologiesServerUpdateStatuses(t *testing.T) {
 			}
 		}
 
+		// midCacheGroup has an ORG_LOC non-topology parent cachegroup
+		if updateStatusByCacheGroup[midCacheGroup].ParentPending {
+			t.Fatalf("expected UpdPending: %t, actual: %t", false, updateStatusByCacheGroup[midCacheGroup].ParentPending)
+		}
 		// edgeCacheGroup is a descendant of midCacheGroup
 		if !updateStatusByCacheGroup[edgeCacheGroup].ParentPending {
 			t.Fatalf("expected UpdPending: %t, actual: %t", true, updateStatusByCacheGroup[edgeCacheGroup].ParentPending)
diff --git a/traffic_ops/testing/api/v3/tc-fixtures.json b/traffic_ops/testing/api/v3/tc-fixtures.json
index 5a19eed..2bbcd85 100644
--- a/traffic_ops/testing/api/v3/tc-fixtures.json
+++ b/traffic_ops/testing/api/v3/tc-fixtures.json
@@ -179,7 +179,8 @@
             "longitude": 0,
             "name": "topology-mid-cg-04",
             "shortName": "tm4",
-            "typeName": "MID_LOC"
+            "typeName": "MID_LOC",
+            "parentCachegroupName": "multiOriginCachegroup"
         },
         {
             "latitude": 0,
diff --git a/traffic_ops/traffic_ops_golang/server/servers_update_status.go b/traffic_ops/traffic_ops_golang/server/servers_update_status.go
index e0ca033..d1d2a67 100644
--- a/traffic_ops/traffic_ops_golang/server/servers_update_status.go
+++ b/traffic_ops/traffic_ops_golang/server/servers_update_status.go
@@ -88,7 +88,9 @@ SELECT s.id, s.cachegroup, s.cdn_id, s.upd_pending, s.reval_pending, s.status, t
 SELECT ps.id, ps.cachegroup, ps.cdn_id, ps.upd_pending, ps.reval_pending, ps.status
 		FROM server ps
 	LEFT JOIN status AS pstatus ON pstatus.id = ps.status
+	LEFT JOIN type t ON ps."type" = t.id
 	WHERE pstatus.name = ANY($1::TEXT[])
+	AND t."name" LIKE ANY($4::TEXT[])
 ), use_reval_pending AS (
 SELECT value::BOOLEAN
 	FROM parameter


[trafficcontrol] 03/03: Remove debug print (#5429)

Posted by oc...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ocket8888 pushed a commit to branch 5.0.x
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git

commit e07f6a14671b89aaeff6c509c493bef23d182a2d
Author: Robert O Butts <ro...@users.noreply.github.com>
AuthorDate: Wed Jan 13 08:59:59 2021 -0700

    Remove debug print (#5429)
    
    (cherry picked from commit b1e98ea0eb5f1d40495547ffc8ab4d975c478717)
---
 lib/go-atscfg/headerrewritemiddotconfig.go | 2 --
 1 file changed, 2 deletions(-)

diff --git a/lib/go-atscfg/headerrewritemiddotconfig.go b/lib/go-atscfg/headerrewritemiddotconfig.go
index 920fb35..f4e7947 100644
--- a/lib/go-atscfg/headerrewritemiddotconfig.go
+++ b/lib/go-atscfg/headerrewritemiddotconfig.go
@@ -20,7 +20,6 @@ package atscfg
  */
 
 import (
-	"fmt"
 	"math"
 	"regexp"
 	"strconv"
@@ -148,7 +147,6 @@ func MakeHeaderRewriteMidDotConfig(
 
 	text := makeHdrComment(hdrComment)
 
-	fmt.Printf("DEBUG moc %v usesmid %v assignedmids %v\n", ds.MaxOriginConnections, ds.Type.UsesMidCache(), len(assignedMids))
 	// write a header rewrite rule if maxOriginConnections > 0 and the ds DOES use mids
 	if ds.MaxOriginConnections > 0 && ds.Type.UsesMidCache() {
 		dsOnlineMidCount := 0


[trafficcontrol] 01/03: Add atscfg parent.config topology comment (#5414)

Posted by oc...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ocket8888 pushed a commit to branch 5.0.x
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git

commit a2ee75cb452deebb9b1e1ded6a1a16b19248d9dd
Author: Robert O Butts <ro...@users.noreply.github.com>
AuthorDate: Wed Jan 13 08:33:46 2021 -0700

    Add atscfg parent.config topology comment (#5414)
    
    (cherry picked from commit c08571586b651372435b627eedcabef479f69519)
---
 lib/go-atscfg/parentdotconfig.go             |  50 +++-
 lib/go-atscfg/parentdotconfig_test.go        | 346 ++++++++++++++++++++++++---
 traffic_ops_ort/atstccfg/cfgfile/wrappers.go |   5 +-
 3 files changed, 365 insertions(+), 36 deletions(-)

diff --git a/lib/go-atscfg/parentdotconfig.go b/lib/go-atscfg/parentdotconfig.go
index 082e1a7..a6e94ac 100644
--- a/lib/go-atscfg/parentdotconfig.go
+++ b/lib/go-atscfg/parentdotconfig.go
@@ -66,6 +66,19 @@ const ParentConfigCacheParamNotAParent = "not_a_parent"
 type OriginHost string
 type OriginFQDN string
 
+// ParentConfigOpts contains settings to configure parent.config generation options.
+type ParentConfigOpts struct {
+	// AddComments is whether to add informative comments to the generated file, about what was generated and why.
+	// Note this does not include the header comment, which is configured separately with HdrComment.
+	// These comments are human-readable and not guarnateed to be consistent between versions. Automating anything based on them is strongly discouraged.
+	AddComments bool
+
+	// HdrComment is the header comment to include at the beginning of the file.
+	// This should be the text desired, without comment syntax (like # or //). The file's comment syntax will be added.
+	// To omit the header comment, pass the empty string.
+	HdrComment string
+}
+
 func MakeParentDotConfig(
 	dses []DeliveryService,
 	server *Server,
@@ -78,7 +91,7 @@ func MakeParentDotConfig(
 	cacheGroupArr []tc.CacheGroupNullable,
 	dss []tc.DeliveryServiceServer,
 	cdn *tc.CDN,
-	hdrComment string,
+	opt ParentConfigOpts,
 ) (Cfg, error) {
 	warnings := []string{}
 
@@ -110,7 +123,10 @@ func MakeParentDotConfig(
 
 	sort.Sort(dsesSortByName(dses))
 
-	hdr := makeHdrComment(hdrComment)
+	hdr := ""
+	if opt.HdrComment != "" {
+		hdr = makeHdrComment(opt.HdrComment)
+	}
 
 	textArr := []string{}
 	processedOriginsToDSNames := map[string]tc.DeliveryServiceName{}
@@ -299,11 +315,12 @@ func MakeParentDotConfig(
 				dsParams,
 				atsMajorVer,
 				dsOrigins[DeliveryServiceID(*ds.ID)],
+				opt.AddComments,
 			)
 			warnings = append(warnings, topoWarnings...)
 			if err != nil {
 				// we don't want to fail generation with an error if one ds is malformed
-				warnings = append(warnings, err.Error()) // GetTopologyParentConfigLine includes error context
+				warnings = append(warnings, err.Error()) // getTopologyParentConfigLine includes error context
 				continue
 			}
 
@@ -330,8 +347,10 @@ func MakeParentDotConfig(
 				if parentSelectAlg := serverParams[ParentConfigParamAlgorithm]; strings.TrimSpace(parentSelectAlg) != "" {
 					algorithm = "round_robin=" + parentSelectAlg
 				}
+				textLine += makeParentComment(opt.AddComments, *ds.XMLID, "")
 				textLine += "dest_domain=" + orgURI.Hostname() + " port=" + orgURI.Port() + " parent=" + *ds.OriginShield + " " + algorithm + " go_direct=true\n"
 			} else if ds.MultiSiteOrigin != nil && *ds.MultiSiteOrigin {
+				textLine += makeParentComment(opt.AddComments, *ds.XMLID, "")
 				textLine += "dest_domain=" + orgURI.Hostname() + " port=" + orgURI.Port() + " "
 				if len(parentInfos) == 0 {
 				}
@@ -343,9 +362,11 @@ func MakeParentDotConfig(
 
 				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)
 				textLine += "\n" // TODO remove, and join later on "\n" instead of ""?
+
 				textArr = append(textArr, textLine)
 			}
 		} else {
@@ -365,6 +386,7 @@ func MakeParentDotConfig(
 				continue
 			}
 
+			text += makeParentComment(opt.AddComments, *ds.XMLID, "")
 			// TODO encode this in a DSType func, IsGoDirect() ?
 			if *ds.Type == tc.DSTypeHTTPNoCache || *ds.Type == tc.DSTypeHTTPLive || *ds.Type == tc.DSTypeDNSLive {
 				text += `dest_domain=` + orgURI.Hostname() + ` port=` + orgURI.Port() + ` go_direct=true` + "\n"
@@ -392,6 +414,7 @@ func MakeParentDotConfig(
 
 				text += `dest_domain=` + orgURI.Hostname() + ` port=` + orgURI.Port() + ` ` + parents + ` ` + secondaryParents + ` ` + roundRobin + ` ` + goDirect + ` qstring=` + parentQStr + "\n"
 			}
+
 			textArr = append(textArr, text)
 		}
 		processedOriginsToDSNames[*ds.OrgServerFQDN] = tc.DeliveryServiceName(*ds.XMLID)
@@ -418,7 +441,10 @@ func MakeParentDotConfig(
 	}
 
 	sort.Sort(sort.StringSlice(textArr))
-	text := hdr + strings.Join(textArr, "") + defaultDestText
+	text := hdr + strings.Join(textArr, "")
+
+	text += makeParentComment(opt.AddComments, "", "") + defaultDestText
+
 	return Cfg{
 		Text:        text,
 		ContentType: ContentTypeParentDotConfig,
@@ -427,6 +453,17 @@ func MakeParentDotConfig(
 	}, nil
 }
 
+// makeParentComment creates the parent line comment and returns it.
+// If addComments is false, returns the empty string. This exists for composability.
+// Either dsName or topology may be the empty string.
+// The returned comment includes a trailing newline.
+func makeParentComment(addComments bool, dsName string, topology string) string {
+	if !addComments {
+		return ""
+	}
+	return "# ds '" + dsName + "' topology '" + topology + "'" + "\n"
+}
+
 type parentConfigDS struct {
 	Name                 tc.DeliveryServiceName
 	QStringIgnore        tc.QStringIgnore
@@ -695,7 +732,7 @@ func getParentDSParams(ds DeliveryService, profileParentConfigParams map[string]
 	return params, warnings
 }
 
-// GetTopologyParentConfigLine returns the topology parent.config line, any warnings, and any error
+// getTopologyParentConfigLine returns the topology parent.config line, any warnings, and any error
 func getTopologyParentConfigLine(
 	server *Server,
 	servers []Server,
@@ -709,6 +746,7 @@ func getTopologyParentConfigLine(
 	dsParams parentDSParams,
 	atsMajorVer int,
 	dsOrigins map[ServerID]struct{},
+	addComments bool,
 ) (string, []string, error) {
 	warnings := []string{}
 	txt := ""
@@ -728,6 +766,7 @@ func getTopologyParentConfigLine(
 		return "", warnings, errors.New("DS " + *ds.XMLID + " topology '" + *ds.Topology + "' not found in Topologies!")
 	}
 
+	txt += makeParentComment(addComments, *ds.XMLID, *ds.Topology)
 	txt += "dest_domain=" + orgURI.Hostname() + " port=" + orgURI.Port()
 
 	serverPlacement, err := getTopologyPlacement(tc.CacheGroupName(*server.Cachegroup), topology, cacheGroups, ds)
@@ -762,6 +801,7 @@ func getTopologyParentConfigLine(
 	txt += getTopologyParentIsProxyStr(serverPlacement.IsLastCacheTier)
 	txt += getParentRetryStr(serverPlacement.IsLastCacheTier, atsMajorVer, dsParams.ParentRetry, dsParams.UnavailableServerRetryResponses, dsParams.MaxSimpleRetries, dsParams.MaxUnavailableServerRetries)
 	txt += "\n"
+
 	return txt, warnings, nil
 }
 
diff --git a/lib/go-atscfg/parentdotconfig_test.go b/lib/go-atscfg/parentdotconfig_test.go
index 2c2b342..f888b2b 100644
--- a/lib/go-atscfg/parentdotconfig_test.go
+++ b/lib/go-atscfg/parentdotconfig_test.go
@@ -28,7 +28,7 @@ import (
 )
 
 func TestMakeParentDotConfig(t *testing.T) {
-	hdr := "myHeaderComment"
+	hdr := ParentConfigOpts{AddComments: false, HdrComment: "myHeaderComment"}
 
 	ds0 := makeParentDS()
 	ds0Type := tc.DSTypeHTTP
@@ -132,7 +132,7 @@ func TestMakeParentDotConfig(t *testing.T) {
 	}
 	txt := cfg.Text
 
-	testComment(t, txt, hdr)
+	testComment(t, txt, hdr.HdrComment)
 
 	if !strings.Contains(txt, "dest_domain=ds0.example.net") {
 		t.Errorf("expected parent 'dest_domain=ds0.example.net', actual: '%v'", txt)
@@ -146,7 +146,7 @@ func TestMakeParentDotConfig(t *testing.T) {
 }
 
 func TestMakeParentDotConfigCapabilities(t *testing.T) {
-	hdr := "myHeaderComment"
+	hdr := ParentConfigOpts{AddComments: false, HdrComment: "myHeaderComment"}
 
 	ds0 := makeParentDS()
 	ds0Type := tc.DSTypeHTTP
@@ -254,7 +254,7 @@ func TestMakeParentDotConfigCapabilities(t *testing.T) {
 	}
 	txt := cfg.Text
 
-	testComment(t, txt, hdr)
+	testComment(t, txt, hdr.HdrComment)
 
 	lines := strings.Split(txt, "\n")
 
@@ -290,7 +290,7 @@ func TestMakeParentDotConfigCapabilities(t *testing.T) {
 }
 
 func TestMakeParentDotConfigMSOSecondaryParent(t *testing.T) {
-	hdr := "myHeaderComment"
+	hdr := ParentConfigOpts{AddComments: false, HdrComment: "myHeaderComment"}
 
 	ds0 := makeParentDS()
 	ds0Type := tc.DSTypeHTTP
@@ -395,7 +395,7 @@ func TestMakeParentDotConfigMSOSecondaryParent(t *testing.T) {
 	}
 	txt := cfg.Text
 
-	testComment(t, txt, hdr)
+	testComment(t, txt, hdr.HdrComment)
 
 	txtx := strings.Replace(txt, " ", "", -1)
 
@@ -405,7 +405,7 @@ func TestMakeParentDotConfigMSOSecondaryParent(t *testing.T) {
 }
 
 func TestMakeParentDotConfigTopologies(t *testing.T) {
-	hdr := "myHeaderComment"
+	hdr := ParentConfigOpts{AddComments: false, HdrComment: "myHeaderComment"}
 
 	ds0 := makeParentDS()
 	ds0Type := tc.DSTypeHTTP
@@ -528,7 +528,7 @@ func TestMakeParentDotConfigTopologies(t *testing.T) {
 	}
 	txt := cfg.Text
 
-	testComment(t, txt, hdr)
+	testComment(t, txt, hdr.HdrComment)
 
 	if !strings.Contains(txt, "dest_domain=ds0.example.net") {
 		t.Errorf("expected parent 'dest_domain=ds0.example.net', actual: '%v'", txt)
@@ -547,7 +547,7 @@ func TestMakeParentDotConfigTopologies(t *testing.T) {
 
 // TestMakeParentDotConfigNotInTopologies tests when a given edge is NOT in a Topology, that it doesn't add a remap line.
 func TestMakeParentDotConfigNotInTopologies(t *testing.T) {
-	hdr := "myHeaderComment"
+	hdr := ParentConfigOpts{AddComments: false, HdrComment: "myHeaderComment"}
 
 	ds0 := makeParentDS()
 	ds0Type := tc.DSTypeHTTP
@@ -666,7 +666,7 @@ func TestMakeParentDotConfigNotInTopologies(t *testing.T) {
 	}
 	txt := cfg.Text
 
-	testComment(t, txt, hdr)
+	testComment(t, txt, hdr.HdrComment)
 
 	if strings.Contains(txt, "dest_domain=ds0.example.net") {
 		t.Errorf("expected parent 'dest_domain=ds0.example.net' to NOT contain Topology DS without this edge: '%v'", txt)
@@ -677,7 +677,7 @@ func TestMakeParentDotConfigNotInTopologies(t *testing.T) {
 }
 
 func TestMakeParentDotConfigTopologiesCapabilities(t *testing.T) {
-	hdr := "myHeaderComment"
+	hdr := ParentConfigOpts{AddComments: false, HdrComment: "myHeaderComment"}
 
 	ds0 := makeParentDS()
 	ds0.ID = util.IntPtr(42)
@@ -821,7 +821,7 @@ func TestMakeParentDotConfigTopologiesCapabilities(t *testing.T) {
 	}
 	txt := cfg.Text
 
-	testComment(t, txt, hdr)
+	testComment(t, txt, hdr.HdrComment)
 
 	if !strings.Contains(txt, "dest_domain=ds0.example.net") {
 		t.Errorf("expected parent 'dest_domain=ds0.example.net' without required capabilities: '%v'", txt)
@@ -835,7 +835,7 @@ func TestMakeParentDotConfigTopologiesCapabilities(t *testing.T) {
 }
 
 func TestMakeParentDotConfigTopologiesOmitOfflineParents(t *testing.T) {
-	hdr := "myHeaderComment"
+	hdr := ParentConfigOpts{AddComments: false, HdrComment: "myHeaderComment"}
 
 	ds0 := makeParentDS()
 	ds0Type := tc.DSTypeHTTP
@@ -960,7 +960,7 @@ func TestMakeParentDotConfigTopologiesOmitOfflineParents(t *testing.T) {
 	}
 	txt := cfg.Text
 
-	testComment(t, txt, hdr)
+	testComment(t, txt, hdr.HdrComment)
 
 	if !strings.Contains(txt, "dest_domain=ds0.example.net") {
 		t.Errorf("expected parent 'dest_domain=ds0.example.net', actual: '%v'", txt)
@@ -978,7 +978,7 @@ func TestMakeParentDotConfigTopologiesOmitOfflineParents(t *testing.T) {
 }
 
 func TestMakeParentDotConfigTopologiesOmitDifferentCDNParents(t *testing.T) {
-	hdr := "myHeaderComment"
+	hdr := ParentConfigOpts{AddComments: false, HdrComment: "myHeaderComment"}
 
 	ds0 := makeParentDS()
 	ds0Type := tc.DSTypeHTTP
@@ -1104,7 +1104,7 @@ func TestMakeParentDotConfigTopologiesOmitDifferentCDNParents(t *testing.T) {
 	}
 	txt := cfg.Text
 
-	testComment(t, txt, hdr)
+	testComment(t, txt, hdr.HdrComment)
 
 	if !strings.Contains(txt, "dest_domain=ds0.example.net") {
 		t.Errorf("expected parent 'dest_domain=ds0.example.net', actual: '%v'", txt)
@@ -1122,7 +1122,7 @@ func TestMakeParentDotConfigTopologiesOmitDifferentCDNParents(t *testing.T) {
 }
 
 func TestMakeParentDotConfigTopologiesMSO(t *testing.T) {
-	hdr := "myHeaderComment"
+	hdr := ParentConfigOpts{AddComments: false, HdrComment: "myHeaderComment"}
 
 	ds1 := makeParentDS()
 	ds1.ID = util.IntPtr(43)
@@ -1240,7 +1240,7 @@ func TestMakeParentDotConfigTopologiesMSO(t *testing.T) {
 	}
 	txt := cfg.Text
 
-	testComment(t, txt, hdr)
+	testComment(t, txt, hdr.HdrComment)
 
 	if !strings.Contains(txt, "dest_domain=ds1.example.net") {
 		t.Errorf("expected parent 'dest_domain=ds1.example.net', actual: '%v'", txt)
@@ -1254,7 +1254,7 @@ func TestMakeParentDotConfigTopologiesMSO(t *testing.T) {
 }
 
 func TestMakeParentDotConfigTopologiesMSOWithCapabilities(t *testing.T) {
-	hdr := "myHeaderComment"
+	hdr := ParentConfigOpts{AddComments: false, HdrComment: "myHeaderComment"}
 
 	ds1 := makeParentDS()
 	ds1.ID = util.IntPtr(43)
@@ -1381,7 +1381,7 @@ func TestMakeParentDotConfigTopologiesMSOWithCapabilities(t *testing.T) {
 	}
 	txt := cfg.Text
 
-	testComment(t, txt, hdr)
+	testComment(t, txt, hdr.HdrComment)
 
 	if !strings.Contains(txt, "dest_domain=ds1.example.net") {
 		t.Errorf("expected parent 'dest_domain=ds1.example.net', actual: '%v'", txt)
@@ -1395,7 +1395,7 @@ func TestMakeParentDotConfigTopologiesMSOWithCapabilities(t *testing.T) {
 }
 
 func TestMakeParentDotConfigMSOWithCapabilities(t *testing.T) {
-	hdr := "myHeaderComment"
+	hdr := ParentConfigOpts{AddComments: false, HdrComment: "myHeaderComment"}
 
 	ds1 := makeParentDS()
 	ds1.ID = util.IntPtr(43)
@@ -1508,7 +1508,7 @@ func TestMakeParentDotConfigMSOWithCapabilities(t *testing.T) {
 	}
 	txt := cfg.Text
 
-	testComment(t, txt, hdr)
+	testComment(t, txt, hdr.HdrComment)
 
 	if !strings.Contains(txt, "dest_domain=ds1.example.net") {
 		t.Errorf("expected parent 'dest_domain=ds1.example.net', actual: '%v'", txt)
@@ -1522,7 +1522,7 @@ func TestMakeParentDotConfigMSOWithCapabilities(t *testing.T) {
 }
 
 func TestMakeParentDotConfigTopologiesMSOParams(t *testing.T) {
-	hdr := "myHeaderComment"
+	hdr := ParentConfigOpts{AddComments: false, HdrComment: "myHeaderComment"}
 
 	ds1 := makeParentDS()
 	ds1.ID = util.IntPtr(43)
@@ -1672,7 +1672,7 @@ func TestMakeParentDotConfigTopologiesMSOParams(t *testing.T) {
 	}
 	txt := cfg.Text
 
-	testComment(t, txt, hdr)
+	testComment(t, txt, hdr.HdrComment)
 
 	if !strings.Contains(txt, "dest_domain=ds1.example.net") {
 		t.Errorf("expected parent 'dest_domain=ds1.example.net', actual: '%v'", txt)
@@ -1698,7 +1698,7 @@ func TestMakeParentDotConfigTopologiesMSOParams(t *testing.T) {
 }
 
 func TestMakeParentDotConfigTopologiesParams(t *testing.T) {
-	hdr := "myHeaderComment"
+	hdr := ParentConfigOpts{AddComments: false, HdrComment: "myHeaderComment"}
 
 	ds1 := makeParentDS()
 	ds1.ID = util.IntPtr(43)
@@ -1848,7 +1848,7 @@ func TestMakeParentDotConfigTopologiesParams(t *testing.T) {
 	}
 	txt := cfg.Text
 
-	testComment(t, txt, hdr)
+	testComment(t, txt, hdr.HdrComment)
 
 	if !strings.Contains(txt, "dest_domain=ds1.example.net") {
 		t.Errorf("expected parent 'dest_domain=ds1.example.net', actual: '%v'", txt)
@@ -1875,7 +1875,7 @@ func TestMakeParentDotConfigTopologiesParams(t *testing.T) {
 
 func TestMakeParentDotConfigSecondaryMode(t *testing.T) {
 
-	hdr := "myHeaderComment"
+	hdr := ParentConfigOpts{AddComments: false, HdrComment: "myHeaderComment"}
 
 	ds0 := makeParentDS()
 	ds0Type := tc.DSTypeHTTP
@@ -2019,7 +2019,7 @@ func TestMakeParentDotConfigSecondaryMode(t *testing.T) {
 	}
 	txt := cfg.Text
 
-	testComment(t, txt, hdr)
+	testComment(t, txt, hdr.HdrComment)
 
 	if !strings.Contains(txt, "dest_domain=ds0.example.net") {
 		t.Errorf("expected parent 'dest_domain=ds0.example.net', actual: '%v'", txt)
@@ -2036,7 +2036,7 @@ func TestMakeParentDotConfigSecondaryMode(t *testing.T) {
 }
 
 func TestMakeParentDotConfigNoSecondaryMode(t *testing.T) {
-	hdr := "myHeaderComment"
+	hdr := ParentConfigOpts{AddComments: false, HdrComment: "myHeaderComment"}
 
 	ds0 := makeParentDS()
 	ds0Type := tc.DSTypeHTTP
@@ -2174,7 +2174,7 @@ func TestMakeParentDotConfigNoSecondaryMode(t *testing.T) {
 	}
 	txt := cfg.Text
 
-	testComment(t, txt, hdr)
+	testComment(t, txt, hdr.HdrComment)
 
 	if !strings.Contains(txt, "dest_domain=ds0.example.net") {
 		t.Errorf("expected parent 'dest_domain=ds0.example.net', actual: '%v'", txt)
@@ -2188,6 +2188,292 @@ func TestMakeParentDotConfigNoSecondaryMode(t *testing.T) {
 	if strings.Contains(txt, "secondary_mode") {
 		t.Errorf("expected no secondary_mode for DSes without ParentConfigParamSecondaryMode parameter, actual: '%v'", txt)
 	}
+
+	if strings.Contains(txt, `topology 't0'`) {
+		t.Errorf("expected no comment with topology name, actual: '%v'", txt)
+	}
+	if strings.Contains(txt, `ds 'ds1'`) {
+		t.Errorf("expected no comment with delivery service name, actual: '%v'", txt)
+	}
+}
+
+func TestMakeParentDotConfigComments(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("http://ds0.example.net")
+
+	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")
+
+	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:      "7",
+			Profiles:   []byte(`["global"]`),
+		},
+	}
+
+	server := makeTestParentServer()
+
+	mid0 := makeTestParentServer()
+	mid0.Cachegroup = util.StrPtr("midCG")
+	mid0.HostName = util.StrPtr("mymid0")
+	mid0.ID = util.IntPtr(45)
+	setIP(mid0, "192.168.2.2")
+
+	mid1 := makeTestParentServer()
+	mid1.Cachegroup = util.StrPtr("midCG")
+	mid1.HostName = util.StrPtr("mymid1")
+	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
+	eCGType := tc.CacheGroupEdgeTypeName
+	eCG.Type = &eCGType
+
+	mCG := &tc.CacheGroupNullable{}
+	mCG.Name = mid0.Cachegroup
+	mCG.ID = mid0.CachegroupID
+	mCGType := tc.CacheGroupMidTypeName
+	mCG.Type = &mCGType
+
+	cgs := []tc.CacheGroupNullable{*eCG, *mCG}
+
+	dss := []tc.DeliveryServiceServer{
+		{
+			Server:          util.IntPtr(*server.ID),
+			DeliveryService: util.IntPtr(*ds0.ID),
+		},
+		{
+			Server:          util.IntPtr(*server.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.HdrComment)
+
+	if !strings.Contains(txt, "dest_domain=ds0.example.net") {
+		t.Errorf("expected parent 'dest_domain=ds0.example.net', actual: '%v'", txt)
+	}
+	if !strings.Contains(txt, "dest_domain=ds1.example.net") {
+		t.Errorf("expected parent 'dest_domain=ds0.example.net', actual: '%v'", txt)
+	}
+	if !strings.Contains(txt, "qstring=myQStringHandlingParam") {
+		t.Errorf("expected qstring from param 'qstring=myQStringHandlingParam', actual: '%v'", txt)
+	}
+	if !strings.Contains(txt, "# ds 'ds1'") {
+		t.Errorf("expected comment with delivery service name, actual: '%v'", txt)
+	}
+}
+
+func TestMakeParentDotConfigCommentTopology(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("http://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)
+	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 := []tc.DeliveryServiceServer{
+		{
+			Server:          util.IntPtr(*server.ID),
+			DeliveryService: util.IntPtr(*ds0.ID),
+		},
+		{
+			Server:          util.IntPtr(*server.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.HdrComment)
+
+	if !strings.Contains(txt, "dest_domain=ds0.example.net") {
+		t.Errorf("expected parent 'dest_domain=ds0.example.net', actual: '%v'", txt)
+	}
+	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, "qstring=myQStringHandlingParam") {
+		t.Errorf("expected qstring from param 'qstring=myQStringHandlingParam', actual: '%v'", txt)
+	}
+	if strings.Contains(txt, "secondary_mode") {
+		t.Errorf("expected no secondary_mode for DSes without ParentConfigParamSecondaryMode parameter, actual: '%v'", txt)
+	}
+	if !strings.Contains(txt, `# ds 'ds1' topology 't0'`) {
+		t.Errorf("expected comment with delivery service and topology, actual: '%v'", txt)
+	}
 }
 
 func makeTestParentServer() *Server {
diff --git a/traffic_ops_ort/atstccfg/cfgfile/wrappers.go b/traffic_ops_ort/atstccfg/cfgfile/wrappers.go
index b189b5b..cd485bd 100644
--- a/traffic_ops_ort/atstccfg/cfgfile/wrappers.go
+++ b/traffic_ops_ort/atstccfg/cfgfile/wrappers.go
@@ -126,7 +126,10 @@ func MakeParentDotConfig(toData *config.TOData, fileName string, hdrCommentTxt s
 		toData.CacheGroups,
 		toData.DeliveryServiceServers,
 		toData.CDN,
-		hdrCommentTxt,
+		atscfg.ParentConfigOpts{
+			HdrComment:  hdrCommentTxt,
+			AddComments: true, // TODO add a CLI flag?
+		},
 	)
 }